চেষ্টা ঘ
কেবল পার্ল ব্যবহার করে একটি সমাধান, হ্যাশগুলির কাঠামোর একটি সাধারণ হ্যাশ ফিরিয়ে দেয়। ওপি জেএসএনের ডেটা ফর্ম্যাটটি স্পষ্ট করার আগে।
#! /usr/bin/perl
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->{$_};
}
}
File::Find
মডিউল ইউনিক্স find
কমান্ডের মতো একইভাবে কাজ করে । JSON
মডিউল JSON, Perl ভেরিয়েবল এবং তাদের ধর্মান্তরিত লাগে।
find({wanted => \&process_dir, no_chdir => 1 }, ".");
process_dir
"।" এর অধীনে প্রতিটি ফাইল / ডিরেক্টরিতে সাবরুটিনকে কল করে বর্তমান কার্যনির্বাহী ডিরেক্টরি থেকে ফাইলের কাঠামোটি পুনরুক্ত করা হবে এবং প্রতিটি ডিরেক্টরি এটির জন্য অনুসন্ধানের জন্য no_chdir
একটি ইস্যু না করার chdir()
জন্য বলুন পারল ।
process_dir
যদি উপস্থিত পরীক্ষিত ফাইলটি ডিরেক্টরি না হয় তবে প্রদান করে:
return if !-d $File::Find::name;
আমরা তখন বিদ্যমান হ্যাশ এর একটি রেফারেন্স দখল %$dirs
মধ্যে $ref
, ফাইল পাথ প্রায় বিভক্ত /
এবং লুপ for
প্রতিটি পাথ জন্য একটি নতুন হ্যাশ কী যোগ করা হয়েছে।
Slm এর মতো একটি ডিরেক্টরি কাঠামো তৈরি করা হয়েছে:
mkdir -p dir{1..5}/dir{A,B}/subdir{1..3}
আউটপুটটি হ'ল:
{
"." : {
"dir3" : {
"dirA" : {
"subdir2" : {},
"subdir3" : {},
"subdir1" : {}
},
"dirB" : {
"subdir2" : {},
"subdir3" : {},
"subdir1" : {}
}
},
"dir2" : {
"dirA" : {
"subdir2" : {},
"subdir3" : {},
"subdir1" : {}
},
"dirB" : {
"subdir2" : {},
"subdir3" : {},
"subdir1" : {}
}
},
"dir5" : {
"dirA" : {
"subdir2" : {},
"subdir3" : {},
"subdir1" : {}
},
"dirB" : {
"subdir2" : {},
"subdir3" : {},
"subdir1" : {}
}
},
"dir1" : {
"dirA" : {
"subdir2" : {},
"subdir3" : {},
"subdir1" : {}
},
"dirB" : {
"subdir2" : {},
"subdir3" : {},
"subdir1" : {}
}
},
"dir4" : {
"dirA" : {
"subdir2" : {},
"subdir3" : {},
"subdir1" : {}
},
"dirB" : {
"subdir2" : {},
"subdir3" : {},
"subdir1" : {}
}
}
}
}
চেষ্টা 2
ঠিক আছে এখন বিভিন্ন ডেটা কাঠামো সহ ...
#! /usr/bin/perl
use warnings;
use strict;
use JSON;
my $encoder = JSON->new->ascii->pretty; # ascii character set, pretty format
my $dirs; # used to build the data structure
my $path=$ARGV[0] || '.'; # use the command line arg or working dir
# Open the directory, read in the file list, grep out directories and skip '.' and '..'
# and assign to @dirs
opendir(my $dh, $path) or die "can't opendir $path: $!";
my @dirs = grep { ! /^[.]{1,2}/ && -d "$path/$_" } readdir($dh);
closedir($dh);
# recurse the top level sub directories with the parse_dir subroutine, returning
# a hash reference.
%$dirs = map { $_ => parse_dir("$path/$_") } @dirs;
# print out the JSON encoding of this data structure
print $encoder->encode($dirs);
sub parse_dir {
my $path = shift; # the dir we're working on
# get all sub directories (similar to above opendir/readdir calls)
opendir(my $dh, $path) or die "can't opendir $path: $!";
my @dirs = grep { ! /^[.]{1,2}/ && -d "$path/$_" } readdir($dh);
closedir($dh);
return undef if !scalar @dirs; # nothing to do here, directory empty
my $vals = []; # set our result to an empty array
foreach my $dir (@dirs) { # loop the sub directories
my $res = parse_dir("$path/$dir"); # recurse down each path and get results
# does the returned value have a result, and is that result an array of at
# least one element, then add these results to our $vals anonymous array
# wrapped in a anonymous hash
# ELSE
# push just the name of that directory our $vals anonymous array
push(@$vals, (defined $res and scalar @$res) ? { $dir => $res } : $dir);
}
return $vals; # return the recursed result
}
এবং তারপরে প্রস্তাবিত ডিরেক্টরি কাঠামোতে স্ক্রিপ্টটি চালানো হচ্ছে ...
./tree2json2.pl .
{
"dir2" : [
"dirB",
"dirA"
],
"dir1" : [
"dirB",
{
"dirA" : [
"dirBB",
"dirAA"
]
}
]
}
সঠিকভাবে পেতে আমি এই সুন্দর জঘন্য কৌশলটি পেয়েছি (বিশেষত "হ্যাশটি যদি সাব ডিরেক্টরিগুলি দেওয়া হয় তবে অ্যারে না দিলে, ওহ UNLESS শীর্ষ স্তর, তারপরে কেবল হ্যাশ" যুক্তি হিসাবে দেওয়া হয়েছে) ic তাই আমি অবাক হব যদি আপনি sed
/ awk
... এর সাথে এমন কিছু করতে পারেন তবে তবে স্টিফেন এখনও এদিকে নজর দেননি আমি বাজি রেখেছি :)