英文:
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 );
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论