我正在尝试构建这样的结构。
{ "file1": "supersong.mp3", "file2": "supersong2.mp3", "file3": "text.txt", "file4": "tex2t.txt", "file5": "text3.txt", "file6": "json.pl", "directory_movies": [ "file1": "supersong.mp3", "file2": "supersong2.mp3", "file3": "text.txt", "file4": "tex2t.txt", "file5": "text3.txt", "file6": "json.pl", "directory_sub_movies": [ "file1": "supersong.mp3", "file2": "supersong2.mp3", "file3": "text.txt", "file4": "tex2t.txt", "file5": "text3.txt", "file6": "json.pl", ]]};
就像我在unix中的任何目录层次结构一样。 所以我们有简单的文件或目录,如果它是目录,它是嵌套的哈希等,递归地。 我需要在perl中将其表示为哈希,我发现最简单的方法是使用File::Find模块。 它工作正常,但我无法弄清楚如何将哈希中的层次结构保存为如上所述嵌套。 这是我的测试脚本。 这正确地确定了当前项目的类型。
sub path_checker { if (-d $File::Find::name) { print "Directory " . $_ . "\n"; } elsif (-f $File::Find::name) { print "File " . $_ . " Category is " . basename($File::Find::dir) . "\n"; } } sub parse_tree { my ($class,$root_path) = @_; File::Find::find(\&path_checker, $root_path); }请帮助修改它以创建我上面描述的结构。 我会很感激。
I am trying to build the structure like this.
{ "file1": "supersong.mp3", "file2": "supersong2.mp3", "file3": "text.txt", "file4": "tex2t.txt", "file5": "text3.txt", "file6": "json.pl", "directory_movies": [ "file1": "supersong.mp3", "file2": "supersong2.mp3", "file3": "text.txt", "file4": "tex2t.txt", "file5": "text3.txt", "file6": "json.pl", "directory_sub_movies": [ "file1": "supersong.mp3", "file2": "supersong2.mp3", "file3": "text.txt", "file4": "tex2t.txt", "file5": "text3.txt", "file6": "json.pl", ]] };
So as any directory hierarchy in my case in unix. So we have simple files or directories, if it is directory it is nested hash and so on recursively. I need to represent it as hash in perl, the easiest way I have found is to use File::Find module. It works correctly but I cannot figure out how to save hierarchy in hash to be nested as above. Here is my test script. That determines type of current item correctly.
sub path_checker { if (-d $File::Find::name) { print "Directory " . $_ . "\n"; } elsif (-f $File::Find::name) { print "File " . $_ . " Category is " . basename($File::Find::dir) . "\n"; } } sub parse_tree { my ($class,$root_path) = @_; File::Find::find(\&path_checker, $root_path); }Please help to modify it to create structure like I have described above. I would be very grateful.
最满意答案
子文件夹也应该是哈希,而不是数组,
use strict; use warnings; # use Data::Dumper; use File::Find; use JSON; sub parse_tree { my ($root_path) = @_; my %root; my %dl; my %count; my $path_checker = sub { my $name = $File::Find::name; if (-d $name) { my $r = \%root; my $tmp = $name; $tmp =~ s|^\Q$root_path\E/?||; $r = $r->{$_} ||= {} for split m|/|, $tmp; #/ $dl{$name} ||= $r; } elsif (-f $name) { my $dir = $File::Find::dir; my $key = "file". ++$count{ $dir }; $dl{$dir}{$key} = $_; } }; find($path_checker, $root_path); return \%root; } print encode_json(parse_tree("/tmp"));Subfolders should also be hashes, not arrays,
use strict; use warnings; # use Data::Dumper; use File::Find; use JSON; sub parse_tree { my ($root_path) = @_; my %root; my %dl; my %count; my $path_checker = sub { my $name = $File::Find::name; if (-d $name) { my $r = \%root; my $tmp = $name; $tmp =~ s|^\Q$root_path\E/?||; $r = $r->{$_} ||= {} for split m|/|, $tmp; #/ $dl{$name} ||= $r; } elsif (-f $name) { my $dir = $File::Find::dir; my $key = "file". ++$count{ $dir }; $dl{$dir}{$key} = $_; } }; find($path_checker, $root_path); return \%root; } print encode_json(parse_tree("/tmp"));更多推荐
发布评论