将目录及其子目录的内容转换为JSON。

huangapple go评论68阅读模式
英文:

Convert the contents of directory and its subdirectories to JSON

问题

以下是翻译好的 Perl 脚本的一部分,用于将目录内容转换为 JSON 格式。请注意,我已经将 HTML 实体字符(如 ")还原为正常字符。

use File::Find;
use JSON;
use strict;
use warnings;

my $dirs = {};
my $encoder = JSON->new->ascii->pretty;
find({ wanted => \&process_dir, no_chdir => 1 }, ".");
print $encoder->encode($dirs);

sub process_dir {
    return if !-d $File::Find::name;
    my $ref = \%$dirs;

    for (split(/\//, $File::Find::name)) {
        $ref->{$_} = {}
          if (!exists $ref->{$_});
        $ref = $ref->{$_};
    }
}

这是你提供的 Perl 脚本的翻译部分。如果你需要关于如何修改脚本以包括每个子目录中的文件作为 JSON 数组的指导,请提出具体的问题,我将乐意帮助你。

英文:

I have the following perl script from this stack exchange question that converts the content of a directory into JSON.

use File::Find; 
use JSON; 
use strict; 
use warnings; 

my $dirs={}; 
my $encoder = JSON->new->ascii->pretty; 
find({wanted => \&process_dir, no_chdir => 1 }, "."); 

print $encoder->encode($dirs); 
sub process_dir { 
    return if !-d $File::Find::name; 
    my $ref=\%$dirs; 

    for(split(/\//, $File::Find::name)) { 
	    $ref->{$_} = {} 
	    if(!exists $ref->{$_}); 
	    $ref = $ref->{$_}; 
  } 
}

I'm running the script using Termux on Android 6.0.

Consider the following directory:

.
 |--server .
 | 		   | - File 1.tmp
 |         | - File 2.sql
 |         | - File 3.sql
 |-- js .
 |         | - File 1.js
 |         | - File 2.js
 |         | - File 3.js
 | -css .
 |         | - File 1.js
 |         | - File 2.js
 |         | - File 3.js
 | -assets .
 |         | - Font-awesome 
 |         |		.
 |		   |		| - webfont.
 |		   |		|		   | - File 2.woff
 |  	   |		|		   | - File 2.woff
 |         |		|		   | - File 3.woff
 |		   |		| - css	.
 |		   |	    |		| - File 2.css
 |         |		|		| - File 2.css
 |         |		|		| - File 3.css
 |         | - Fonts
 |		   |	    | - ps	.
 |		   |	    |	    | - File 2.woff
 |         |		|		| - File 2.css
 |         |	    |		| - File 3.txt
 |         | - images 
 |         |		| - File 1.png
 |		   |	    | - File 2.png
 |		   |		|	- File 3.svg

The script returns the following if I execute it in the above directory:

{
"." : {
      "server" : {},                               
	  "js" : {},
      "css" : {},
      "assets" : {
         "fonts" : {                                       
			"ps":{}
         },
         "images" : {},
         "font-awesome" : {
            "css" :{},                                     
			"webfonts" : {}
         }
      }                                 
     }                                            
    }

I'm trying to edit the script to additionally include the files in each subdirectory as a Js array (if it's possible using perl + JSON Module, or, just Perl)

Eg [Edit]

{
"." : {
      "server" : {"Files": ["File1", "File2", "File n"]},
	  /* Or just "server" : ["File1", "File2", "File n"], ... */
      "js" : {"Files": ["File1", "File2", "File n"]},                                
      "assets" : {
         "fonts" : {                                       
             "ps":{"Files": ["File1", "File2", "File n"]}
          },
         "images" : {"Files": ["File1", "File2", "File n"]},
         "font-awesome" : {
         "css" : {"Files": ["File1", "File2", "File n"]}                    
         "webfonts" : {"Files": ["File1", "File2", "File n"]}
     }
  }     
 }                                            
}

Is this achievable? If so, how should I go about it? I'm relatively new to perl and I'm having a hard time wrapping my head around this.

答案1

得分: 2

我尝试过并决定将文件名移动到具有特殊键__files__的条目中。如果您有一个以这样命名的目录,这将会中断。

use File::Find;
use JSON;
use strict;
use warnings;
use 5.12.0;
use Data::Dumper;
my $dirs={};
my $encoder = JSON->new->ascii->pretty;
find({wanted => \&process_dir, no_chdir => 1 }, ".");
print $encoder->encode($dirs);
sub process_dir {
    my $full_name = $File::Find::name;
    my $ref=$dirs;
    if (-d $full_name ) {
        for (split(/\//, $full_name)) {  # only directories
            $ref->{$_} ||= {};  # create the next level if it does not exist
            $ref = $ref->{$_};  # move to the next level
        }
    } else {
        for (split(/\//, $full_name)){  # n directories and 1 filename
            if (exists $ref->{$_}) {    # it's a directory
                $ref = $ref->{$_}
            } else {
                push @{$ref->{__files__}}, $_;  # it's a filename
                # $ref->{$_} = '_is_file_';
            }
        }
    }
}
英文:

I gave it a try and decided to move the file names to an entry with the special key __files__. This will break if you have a directory named like that.

use File::Find; 
use JSON; 
use strict; 
use warnings;
use 5.12.0;
use Data::Dumper;
my $dirs={}; 
my $encoder = JSON->new->ascii->pretty; 
find({wanted => \&process_dir, no_chdir => 1 }, "."); 
print $encoder->encode($dirs); 
sub process_dir { 
    my $full_name = $File::Find::name;
    my $ref=$dirs; 
    if (-d $full_name ) {
        for (split(/\//, $full_name)) {  # only directories
            $ref->{$_} ||= {};  # create the next level if it does not exist
            $ref = $ref->{$_};  # move to the next level         
        }
    } else {
        for (split(/\//, $full_name)){  # n directories and 1 filename
            if (exists $ref->{$_}) {    # it's a directory
                $ref = $ref->{$_}
            } else {
                push @{$ref->{__files__}}, $_;  # it's a filename
                # $ref->{$_} = '_is_file_';
            }
        }
    }
}

答案2

得分: 0

以下是翻译好的部分:

以下的代码段将目录结构存储到哈希表中,然后将其转换为JSON格式:

use strict;
use warnings;

use JSON;

my $data;

my $dir = shift // '.';   # // 正确的网站高亮

$data->{$dir} = traverse($dir);

my $encoder = JSON->new->ascii->pretty;

print $encoder->encode($data);

sub traverse {
    my $dir = shift;

    my($dh,$data);

    $data->{'files'} = ();

    opendir($dh, $dir)
        or die "Could not open $dir";

    while( my $name = readdir($dh) ) {
        next if $name eq '.' or $name eq '..';

        my $path = "$dir/$name";

        $data->{$name} = traverse($path) if -d $path;
        push @{$data->{'files'}}, $name  if -f $path;
    }

    closedir $dh;

    return $data;
}
英文:

Following piece of code puts directory structure into hash and then converts it into JSON format

use strict;
use warnings;

use JSON;

my $data;

my $dir = shift // '.';   # // correct website highlighting

$data->{$dir} = traverse($dir);

my $encoder = JSON->new->ascii->pretty; 

print $encoder->encode($data); 

sub traverse {
	my $dir = shift;
	
	my($dh,$data);
	
	$data->{'files'} = ();

	opendir($dh, $dir)
		or die "Could not open $dir";

	while( my $name = readdir($dh) ) {
		next if $name eq '.' or $name eq '..';

		my $path = "$dir/$name";

		$data->{$name} = traverse($path) if -d $path;
		push @{$data->{'files'}}, $name  if -f $path;
	}
	
	closedir $dh;
	
	return $data;
}

答案3

得分: 0

以下是代码的翻译部分:

use strict;
use warnings;

use JSON;

my $data;

my $dir = shift // '.';    # // 正确的网站高亮

$data->{$dir} = traverse($dir, $dir);

my $encoder = JSON->new->ascii->pretty;

print $encoder->encode($data);

sub traverse {
    my $dir  = shift;
    my $name = shift;

    my($dh,@data,%ret);

    opendir($dh, $dir)
        or die "无法打开 $dir";


    while( my $name = readdir($dh) ) {
        next if $name eq '.' or $name eq '..';

        my $path = "$dir/$name";

        push @data, traverse($path,$name) if -d $path;
        push @data, $name                 if -f $path;
    }

    closedir $dh;

    return ( $name => \@data );
}

希望这对你有所帮助。如果有任何其他需要,请随时提问。

英文:

Other variation of the code: files are array elements, directories are hash with key directory name and content as array, then converted to JSON format

use strict;
use warnings;

use JSON;

my $data;

my $dir = shift // '.';    # // correct website highlighting

$data->{$dir} = traverse($dir, $dir);

my $encoder = JSON->new->ascii->pretty; 

print $encoder->encode($data); 


sub traverse {
	my $dir  = shift;
	my $name = shift;
	
	my($dh,@data,%ret);
	
	opendir($dh, $dir)
		or die "Could not open $dir";


	while( my $name = readdir($dh) ) {
		next if $name eq '.' or $name eq '..';

		my $path = "$dir/$name";

		push @data, traverse($path,$name) if -d $path;
		push @data, $name                 if -f $path;
	}
	
	closedir $dh;
	
	return ( $name => \@data );
}

huangapple
  • 本文由 发表于 2020年1月6日 02:45:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/59603087.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定