将目录及其子目录的内容转换为 JSON
Convert the contents of directory and its subdirectories to JSON
我有以下来自 this 堆栈交换问题的 perl 脚本,可将目录的内容转换为 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->{$_};
}
}
我是 运行 在 Android 6.0 上使用 Termux 的脚本。
考虑以下目录:
.
|--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
脚本returns如果我在上面的目录中执行它如下:
{
"." : {
"server" : {},
"js" : {},
"css" : {},
"assets" : {
"fonts" : {
"ps":{}
},
"images" : {},
"font-awesome" : {
"css" :{},
"webfonts" : {}
}
}
}
}
我正在尝试编辑脚本以将每个子目录中的文件作为 Js 数组另外包含(如果可以使用 perl + JSON 模块,或者仅使用 Perl)
例如 [编辑]
{
"." : {
"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"]}
}
}
}
}
这可以实现吗?如果是这样,我应该怎么做?我对 perl 比较陌生,我很难理解这个问题。
我试了一下,决定将文件名移动到具有特殊键 __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_';
}
}
}
}
下面一段代码将目录结构放入hash,然后转换成JSON格式
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;
}
代码的其他变体:文件是数组元素,目录是散列 关键目录名和内容为数组,然后转换为JSON格式
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 );
}
我有以下来自 this 堆栈交换问题的 perl 脚本,可将目录的内容转换为 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->{$_};
}
}
我是 运行 在 Android 6.0 上使用 Termux 的脚本。
考虑以下目录:
.
|--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
脚本returns如果我在上面的目录中执行它如下:
{
"." : {
"server" : {},
"js" : {},
"css" : {},
"assets" : {
"fonts" : {
"ps":{}
},
"images" : {},
"font-awesome" : {
"css" :{},
"webfonts" : {}
}
}
}
}
我正在尝试编辑脚本以将每个子目录中的文件作为 Js 数组另外包含(如果可以使用 perl + JSON 模块,或者仅使用 Perl)
例如 [编辑]
{
"." : {
"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"]}
}
}
}
}
这可以实现吗?如果是这样,我应该怎么做?我对 perl 比较陌生,我很难理解这个问题。
我试了一下,决定将文件名移动到具有特殊键 __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_';
}
}
}
}
下面一段代码将目录结构放入hash,然后转换成JSON格式
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;
}
代码的其他变体:文件是数组元素,目录是散列 关键目录名和内容为数组,然后转换为JSON格式
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 );
}