ট্রি কমান্ডের আউটপুটটিকে জসন ফর্ম্যাটে রূপান্তর করুন


10

* নিক্স কমান্ড "ট্রি" এর আউটপুটটিকে JSON ফর্ম্যাটে রূপান্তর করার জন্য কি কোনও সুবিধাজনক উপায় আছে?

সম্পাদনা: আমার মনে হয় আমি আমার সমস্যাটি যথেষ্টভাবে বর্ণনা করতে পারি নি। আমার লক্ষ্যটি এমন কিছু রূপান্তর করা:

.
|-- dir1
|   |-- dirA
|   |   |-- dirAA
|   |   `-- dirBB
|   `-- dirB
`-- dir2
    |-- dirA
    `-- dirB

মধ্যে:

{"dir1" : [{"dirA":["dirAA", "dirAB"]}, "dirB"], "dir2": ["dirA", "dirB"]}

আপনি কীভাবে জেএসএন-এ এই্যাপস্যাপুলেটেড দেখতে পাবেন? আপনি একটি উদাহরণ এবং প্রত্যাশিত ফলাফল দিতে পারেন?
ড্রো স্লোয়ান

@ শ্রাবস্লোয়ান আমি পোস্টটি সম্পাদনা করে একটি উদাহরণ দেখানোর জন্য করেছি
রাউন্ড্রোবিন

dir1/dirAউপ-ডিরেক্টরি থাকলে আপনি কী পাবেন ?
সিজেএম

{"dir1" : [{"dirA":["dirAA", "dirAB"]}, "dirB"], "dir2": ["dirA", "dirB"]}
রাউন্ড্রোবিন

@ বাউসবিগ - আমার মনে হয় না আপনি এটি সমস্ত পথ ধরেই ভেবেছিলেন। treeকমান্ড ডান টুল নয়। আমি করতে ls -Rবা তার findপরিবর্তে ঝোঁক হতে পারে ।
slm

উত্তর:


6

চেষ্টা ঘ

কেবল পার্ল ব্যবহার করে একটি সমাধান, হ্যাশগুলির কাঠামোর একটি সাধারণ হ্যাশ ফিরিয়ে দেয়। ওপি জেএসএনের ডেটা ফর্ম্যাটটি স্পষ্ট করার আগে।

#! /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... এর সাথে এমন কিছু করতে পারেন তবে তবে স্টিফেন এখনও এদিকে নজর দেননি আমি বাজি রেখেছি :)


ওহ সাব ডায়ারের ফর্ম্যাটটি এখন কিছুটা আলাদা, উপরের আউটপুট ফর্ম্যাটটি কি কোনও সমস্যা হতে চলেছে?
ড্রইং স্লোয়ান

হ্যাঁ আমি নিজেই সেই ফর্ম্যাটটিতে ঘুরছি। আমি নিশ্চিত নই যে এটি কোনও প্রকারে স্ট্যান্ডার্ড, শেল্ফটি এটির মতো সরবরাহ করবে এমন খুব বেশি কিছু খুঁজে পাবে না, তবে আপনার পদ্ধতির একটি নির্দিষ্ট উন্নতি is
slm

এটি দিয়ে কোনও অগ্রগতি করছেন? 8-)
স্ল্যাম

আমি অন্য প্রশ্নের উপর একটি স্ল্যাম-স্টাইল-এসিআই-নেটওয়ার্ক-এ-গ্রামের সাথে ট্র্যাক পেয়েছি (পিট স্টপ কারণ এটি আমার মাথা স্পিন করছে)। আমি আমার ক্যাফিন / রক্তের অনুপাতটি সংশোধন করার জন্য একটি চুপা তৈরি করব এবং অন্য চেহারা নেব।
ড্র স্লোয়ান

asciio হ'ল এগুলি তৈরির সরঞ্জাম
স্ল্যাম

13

সংস্করণ 1.7 জেএসএনের জন্য সমর্থন অন্তর্ভুক্ত:
http://mama.indstate.edu/users/ice/tree/changes.html

manপৃষ্ঠা প্রতি (নীচে XML/JSON/HTML OPTIONS):

-J     Turn on JSON output. Outputs the directory tree as an JSON formatted array.

যেমন

$ tree -J                                                                                                 

/home/me/trash/tree-1.7.0
[{"type":"directory","name": ".","contents":[
    {"type":"file","name":"CHANGES"},
    {"type":"file","name":"color.c"},
    {"type":"file","name":"color.o"},
    {"type":"directory","name":"doc","contents":[
      {"type":"file","name":"tree.1"},
      {"type":"file","name":"tree.1.fr"},
      {"type":"file","name":"xml.dtd"}
    ]},
    {"type":"file","name":"hash.c"},
    {"type":"file","name":"hash.o"},
    {"type":"file","name":"html.c"},
    {"type":"file","name":"html.o"},
    {"type":"file","name":"INSTALL"},
    {"type":"file","name":"json.c"},
    {"type":"file","name":"json.o"},
    {"type":"file","name":"LICENSE"},
    {"type":"file","name":"Makefile"},
    {"type":"file","name":"README"},
    {"type":"file","name":"strverscmp.c"},
    {"type":"file","name":"TODO"},
    {"type":"file","name":"tree"},
    {"type":"file","name":"tree.c"},
    {"type":"file","name":"tree.h"},
    {"type":"file","name":"tree.o"},
    {"type":"file","name":"unix.c"},
    {"type":"file","name":"unix.o"},
    {"type":"file","name":"xml.c"},
    {"type":"file","name":"xml.o"}
  ]},
  {"type":"report","directories":1,"files":26}
]

5

পার্ল এবং জেএসএন পার্ল মডিউলটি ব্যবহার করার একটি উপায় এখানে।

$ tree | perl -e 'use JSON; @in=grep(s/\n$//, <>); \
     print encode_json(\@in)."\n";'

উদাহরণ

কিছু নমুনা ডেটা তৈরি করুন।

$ mkdir -p dir{1..5}/dir{A,B}

এটি দেখতে কেমন দেখাচ্ছে তা এখানে:

$ tree 
.
|-- dir1
|   |-- dirA
|   `-- dirB
|-- dir2
|   |-- dirA
|   `-- dirB
|-- dir3
|   |-- dirA
|   `-- dirB
|-- dir4
|   |-- dirA
|   `-- dirB
`-- dir5
    |-- dirA
    `-- dirB

15 directories, 0 files

পার্ল কমান্ডটি ব্যবহার করে এখানে একটি রান করুন:

$ tree | perl -e 'use JSON; @in=grep(s/\n$//, <>); print encode_json(\@in)."\n";'

যা এই আউটপুটটি প্রদান করে:

[".","|-- dir1","|   |-- dirA","|   `-- dirB","|-- dir2","|   |-- dirA","|   `-- dirB","|-- dir3","|   |-- dirA","|   `-- dirB","|-- dir4","|   |-- dirA","|   `-- dirB","`-- dir5","    |-- dirA","    `-- dirB","","15 directories, 0 files"]

দ্রষ্টব্য: এটি কেবলমাত্র আউটপুটটির একটি এনপ্যাপুলেশন tree। নেস্টেড হায়ারার্কি নয়। আমি পরামর্শ দেওয়ার পরে ওপি প্রশ্নটি পরিবর্তন করেছে!


দুঃখিত আমি মনে করি আমি আমার সমস্যাটি যথেষ্টভাবে বর্ণনা করতে পারি নি। আমার লক্ষ্য হ'ল: | - dir1 | এর মতো কিছু রূপান্তর করা | - dirA | | - dirB | - dir2 | | - dirA | | - dirB in: {"dir1": ["dirA", "dirB"], "dir2": ["dirA", "dirB"]
round

@ বাউসবিগ - কোনও সমস্যা নেই। আপনার উত্তরটি সম্পাদনা করুন এবং আপনি যা চান তার একটি উদাহরণ যুক্ত করুন।
slm

উপাত্ত কাঠামোটি পাইথন অবজেক্টের মতো দেখায়। পাইথন সম্পর্কে আমার প্রায় কোনও জ্ঞান নেই তাই আমি সাহায্য করতে পারি না তবে আমি অনুমান করতে পারি যে এই ধরণের কাঠামোটি সেখানে নির্মাণ করা সহজ।
টেরডন

@ এটারডন - আমি এটি দ্রাবিতে রেখে এসেছি, এটি আমাদের কাছে হ্যাশ অফ হ্যাশ কাঠামোর মতো লাগছিল।
slm

2

আমি কিছু জেএসএন বা এক্সএমএল ফাইলে একটি লিনাক্স ফোল্ডার / ফাইল ট্রি আউটপুট দেওয়ার উপায়ও সন্ধান করছিলাম। এই সাধারণ টার্মিনাল কমান্ডটি ব্যবহার করবেন না কেন:

tree --dirsfirst --noreport -n -X -i -s -D -f -o my.xml

সুতরাং, কেবল লিনাক্স treeকমান্ড করুন এবং আপনার নিজস্ব পরামিতিগুলি কনফিগার করুন। এখানে -Xএক্সএমএল আউটপুট দেয়। আমার জন্য, এটি ঠিক আছে, এবং আমি অনুমান করি যে এক্সএমএলকে জেএসওনে রূপান্তর করার জন্য কিছু স্ক্রিপ্ট রয়েছে।


1

আপনি এই আদেশটি চেষ্টা করতে পারেন:

tree -a -J -o *filename*

আপনার পছন্দসই আউটপুট ফাইলের নামের সাথে ফাইলের নামটি প্রতিস্থাপন করুন।


Jকমান্ডের জন্য এমন কোনও পতাকা নেই tree!!

উপবিষ্ট করুন: বৃক্ষ v1.7.0 এ একটি পতাকা জে আছে ... চিয়ার্স

1

এটি কাজ করে। https://gist.github.com/debodirno/18a21df0511775c19de8d7ccbc99cb72

import os
import sys
import json

def tree_path_json(path):
    dir_structure = {}
    base_name = os.path.basename(os.path.realpath(path))
    if os.path.isdir(path):
        dir_structure[base_name] = [ tree_path_json(os.path.join(path, file_name))\
         for file_name in os.listdir(path) ]
    else:
        return os.path.basename(path)
    return dir_structure

if len(sys.argv) > 1:
    path = sys.argv[1]
else:
    path = '.'

print json.dumps(tree_path_json(path), indent = 4, separators = (', ', ' : '))

আমি এটি পাই না
পিয়ের.ভ্রিয়েন্স

1
সুতরাং এটি গাছ কাঠামোটিকে জসনে রূপান্তরিত করে। একটি ডিরেক্টরিতে এই কোডটি চালান এবং এটি প্রশ্নের উত্তর অনুযায়ী জসন তৈরি করবে।
দেবোদিরনো চন্দ্র
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.