ट्री कमांड के आउटपुट को json फॉर्मेट में कन्वर्ट करें


10

क्या * nix कमांड "ट्री" के आउटपुट को JSON फॉर्मेट में बदलने का एक सुविधाजनक तरीका है?

संपादित करें: मुझे लगता है कि मैंने अपनी समस्या का अच्छी तरह से वर्णन नहीं किया है। मेरा लक्ष्य कुछ इस तरह बदलना है:

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

में:

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

आप उस JSON में कैसे देखे जाने की उम्मीद करेंगे? क्या आप एक उदाहरण और अपेक्षित परिणाम दे सकते हैं?
द्रविण स्लोन

@DravSloan मैंने एक उदाहरण दिखाने के लिए पोस्ट को संपादित किया
राउंडरोबिन

यदि dir1/dirAउपनिर्देशिकाएँ हों, तो आप क्या पाने की उम्मीद करेंगे ?
cjm

{"dir1" : [{"dirA":["dirAA", "dirAB"]}, "dirB"], "dir2": ["dirA", "dirB"]}
राउंडरोबिन

@BausTheBig - मुझे नहीं लगता कि आपने इस तरह से सोचा है। treeआदेश सही उपकरण नहीं है। मैं करने के लिए ls -Rया findइसके बजाय इच्छुक हो सकता है ।
slm

जवाबों:


6

प्रयास करना १

एक उपाय सिर्फ पर्ल का उपयोग करके, हैश संरचना का एक साधारण हैश लौटाता है। ओपी से पहले JSON के डेटा प्रारूप को स्पष्ट किया।

#! /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 में पर्ल चर और उन्हें धर्मान्तरित लेता है।

find({wanted => \&process_dir, no_chdir => 1 }, ".");

वर्तमान कार्यशील निर्देशिका सबरूटीन कॉल करने से फ़ाइल संरचना नीचे पुनरावृति करेंगे process_dirतहत प्रत्येक फ़ाइल / निर्देशिका के लिए "।", और no_chdirबताई पर्ल एक जारी करने के लिए नहीं chdir()प्रत्येक निर्देशिका यह पाता है के लिए।

process_dir वर्तमान परीक्षित फ़ाइल निर्देशिका नहीं है, तो रिटर्न:

return if !-d $File::Find::name;

हम तो मौजूदा हैश का एक संदर्भ हड़पने %$dirsमें $ref, फ़ाइल पथ के आसपास विभाजित /के साथ और पाश forप्रत्येक पथ के लिए एक नया हैश कुंजी जोड़ने।

एसएलएम जैसी निर्देशिका संरचना बनाना:

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" : {}
         }
      }
   }
}

प्रयास २

विभिन्न डेटा संरचना के साथ अब ठीक है ...

#! /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"
         ]
      }
   ]
}

मैं सही पाने के लिए इस बहुत लानत मुश्किल पाया (विशेष रूप से "हैश अगर उप निर्देशिका, सरणी अगर नहीं, ओह शीर्ष शीर्ष स्तर, तो बस वैसे भी" तर्क है) दिया। तो मुझे आश्चर्य होगा कि यह कुछ ऐसा था जो आप के साथ कर सकते थे sed/ awk... लेकिन तब स्टीफन ने इस पर ध्यान नहीं दिया था फिर भी मैंने शर्त लगाई :)


ओह, सब डार का प्रारूप अब कुछ अलग है, क्या उपरोक्त आउटपुट प्रारूप एक मुद्दा बनने जा रहा है?
द्रविण स्लोअन

हाँ, मैं खुद उस प्रारूप पर घूम रहा हूँ। मुझे यकीन नहीं है कि यह किसी भी तरह से मानक है, शेल्फ से बहुत कुछ नहीं पा सकता है जो इसे ऐसा प्रदान करेगा, लेकिन आपका दृष्टिकोण एक निश्चित सुधार है।
slm

इसके साथ कोई प्रगति कर रहा है? 8-)
slm :

मैं एक और सवाल पर गड्ढा-शैली-एस्की-नेटवर्क-ए-ग्राम के साथ ट्रैक हो गया (गड्ढे बंद करो क्योंकि यह मेरा सिर स्पिन कर रहा था)। मैं अपने कैफ़ीन / रक्त के अनुपात को सही करने के लिए एक कॉप्पा बनाऊंगा और दूसरा लुक लूंगा।
द्रविड़ स्लोन

asciio उन्हें बनाने के लिए उपकरण है
SLM

14

संस्करण 1.7 में JSON के लिए समर्थन शामिल है:
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

यहाँ पर्ल और JSON पर्ल मॉड्यूल का उपयोग करने का एक तरीका है।

$ 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 में: { "dir1": [ "Dira", "dirB"], "dir2": [ "Dira", "dirB"]}
roundrobin

@BausTheBig - कोई समस्या नहीं। अपना उत्तर संपादित करें और जो आप चाहते हैं उसका एक उदाहरण जोड़ें।
SLM

डेटा संरचना ओपी को लगता है कि पायथन ऑब्जेक्ट की तरह दिखता है। मुझे पाइथन का लगभग कोई ज्ञान नहीं है इसलिए मैं मदद नहीं कर सकता लेकिन मुझे लगता है कि इस तरह की संरचना का निर्माण करना आसान है।
terdon

@terdon - मैंने इसे द्रविड़ पर छोड़ दिया, यह हमारे लिए हैश संरचना की तरह लग रहा था।
SLM

2

मैं भी कुछ JSON या XML फ़ाइल के लिए एक लिनक्स फ़ोल्डर / फ़ाइल ट्री आउटपुट के लिए एक रास्ता खोज रहा था। इस सरल टर्मिनल कमांड का उपयोग क्यों न करें:

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

तो, बस लिनक्स treeकमांड, और अपने स्वयं के मापदंडों को कॉन्फ़िगर करें। यहां -Xएक्सएमएल आउटपुट देता है। मेरे लिए, यह ठीक है, और मुझे लगता है कि XML को JSON में बदलने के लिए कुछ स्क्रिप्ट है।


1

आप इस आदेश को आजमा सकते हैं:

tree -a -J -o *filename*

फ़ाइल नाम को अपने वांछित आउटपुट फ़ाइल नाम से बदलें।


Jआज्ञा के लिए ऐसा कोई झंडा नहीं है tree!!

अपवोट: पेड़ v1.7.0 पर एक ध्वज J है ... चीयर्स
drl

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
तो यह पेड़ की संरचना को जसन में बदल देता है। एक निर्देशिका पर इस कोड को चलाएं और यह प्रश्न में संकेत के रूप में json का उत्पादन करेगा।
देबोधिरनो चन्द्र
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.