2012-04-19 22 views
18

Ist es möglich, ein Bash-Skript zu verwenden, um die Ausgabe des ls zu einem JSON-Array zu formatieren? Um gültig zu sein, müssen alle Namen der Verzeichnisse und Dateien in doppelte Anführungszeichen gesetzt werden, getrennt durch ein Komma, und das Ganze muss in eckige Klammern gesetzt werden. I.e. konvertieren:konvertieren Bash 'ls' Ausgabe in JSON-Array

[email protected]:~/Desktop$ ls 
foo.txt bar baz 

zu

[ "foo.txt", "bar", "baz" ] 

edit: ich stark lieber etwas, das über alle meine Linux-Server arbeitet; also eher nicht auf Python angewiesen, sondern eine reine Bash-Lösung.

+0

Sie das falsche Werkzeug für den Job. Wenn Sie sich Sorgen machen, dass Python nicht verfügbar ist, verwenden Sie perl. Es sollte auf fast allen Linux-Servern sein. – gpojd

+0

Wer weiß, wie man das über das json manipulation tool jq macht? http://stedolan.github.io/jq/manual/ – rektide

Antwort

12

Verwenden Perl als Geber; es ist garantiert nicht-Buggy sein, ist überall, und mit Rohren, es ist immer noch recht sauber:

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

Failed für mich, aber die awk/sed Antwort funktionierte. – FakeRainBrigand

+1

Sie müssen das JSON-Perl-Modul installieren, aber das funktioniert! – slm

+4

** - 1 **. Dies leidet unter dem klassischen [Parsing LS] (http://mywiki.wooled.org/ParsingLs) Problem. Besser, es in einer for-Schleife zu machen und die Pfeife vollständig zu vermeiden. Siehe Glenn Jackmans Antwort für den richtigen Ansatz. – ghoti

0

Persönlich würde ich Code-Skript, das den Befehl ls ausführen würde, senden Sie die Ausgabe in eine Datei Ihrer Wahl beim Analysieren der Ausgabe, um es in ein gültiges JSON-Format zu formatieren.

Ich bin sicher, dass eine einfache Bash-Datei die Arbeit machen wird.

Bash ouput

13

Ja, aber die Ecke Fälle und Unicode-Behandlung werden Sie die Wand fahren. Besser an eine Skriptsprache delegieren, die sie nativ unterstützt.

$ ls 
あ a "a" à a b 私 
$ python -c 'import os, json; print json.dumps(os.listdir("."))' 
["\u00e0", "\"a\"", "\u79c1", "a b", "\u3042", "a"] 
+0

Danke, aber wirklich bevorzugen etwas, das im Allgemeinen auf jedem Linux-Server funktioniert; also habe ich lieber eine reine Bash-Lösung. – Jeroen

+6

99,8% der Linux-Server da draußen haben Python verfügbar; Allerdings müssen Sie für ältere Versionen von Python eventuell simplejson verwenden. –

+1

Ein Server ohne Python = Hell. Sie werden wahrscheinlich bald auch eine Perl-Lösung bekommen. – KurzedMetal

0

Können Sie nicht ein Python-Skript wie folgt verwenden?

myOutput = subprocess.check_output["ls"] 
output = ["+str(e)+" for e in myOutput] 
return output 

ich nicht überprüfen, ob es funktioniert, aber Sie können die Spezifikation here

-1

Sollte recht einfach finden.

$ cat ls2json.bash 
#!/bin/bash 
echo -n '[' 
for FILE in $(ls | sed -e 's/"/\\"/g') 
do 
echo -n \"${FILE}\", 
done 
echo -en \\b']' 

dann laufen:

$ ./ls2json.bash > json.out 

aber Python wäre noch einfacher

import os 
directory = '/some/dir' 
ls = os.listdir(directory) 
dirstring = str(ls) 
print dirstring.replace("'",'"') 
+0

Können Sie das Komma hinzufügen, das zwei Strings trennt? – Jeroen

+0

oh, ja, vergaß in der Übersetzung, behoben, Problem gibt es, dass es ein nachkommendes Komma geben wird. hmm. – TaoJoannes

+1

Nun, das Schwierige ist, dass nach dem letzten Element, kurz vor dem – Jeroen

1

Hier ist eine bash Linie

echo '[' ; ls --format=commas|sed -e 's/^/\"/'|sed -e 's/,$/\",/'|sed -e 's/\([^,]\)$/\1\"\]/'|sed -e 's/, /\", \"/g' 

Wird nicht richtig mit " beschäftigen, \ oder einige Kommas im Namen der Datei. Wenn ls Zeilenumbrüche zwischen Dateinamen setzt, wird dies auch der Fall sein.

+0

Behandelt auch keine Registerkarten, Zeilenumbrüche oder andere Steuerzeichen in Dateinamen. – ghoti

10

Hallo können Sie das tun mit sed und awk:

ls | awk ' BEGIN { ORS = ""; print "["; } { print "\/\@"$0"\/\@"; } END { print "]"; }' | sed "s^\"^\\\\\"^g;s^\/\@\/\@^\", \"^g;s^\/\@^\"^g" 

EDIT: aktualisiert, um das Problem mit " und Räume zu lösen. Ich benutze /@ als Ersatzmuster für ", da / kein gültiges Zeichen für den Dateinamen ist.

+0

Beachten Sie, dass diese Lösung doppelte Anführungszeichen, die in dem Name, z. eine Datei mit dem Namen 'foo \" bar "erscheint als' "foo" bar "' anstelle von '" foo \ "bar" '. – Phrogz

+0

auch Verzeichnisse mit einem Leerzeichen im Namen sind problematisch. – Jeroen

+0

Ich löste diese beiden Ausgaben – Tronix117

-1

Verwenden Sie keine bash, verwenden Sie eine Skriptsprache.Ungeprüfte Perl Beispiel:

use JSON; 
my @ls_output = `ls`; ## probably better to use a perl module to do this, like DirHandle 
print encode_json(@ls_output); 
7
json="[" 
sep="" 
for file in *; do 
    file=${file//\\/\\\\} 
    file=${file//\"/\\\"} 
    printf -v json '%s%s"%s"' "$json" "$sep" "$file" 
    sep=, 
done 
json+="]" 
+1

Ich mag, wie Sie das Komma zwischen Elementen behandelt haben! – raychi

0

ich auch nach einer Möglichkeit zur Ausgabe eines Linux-Ordner-/Dateibaums zu einem gewissen JSON oder XML-Datei gesucht wurde. Warum nicht diesen einfachen Terminal-Befehl verwenden:

$ Baum --dirsfirst --noreport -n -X -i es -D -f -o my.xml

so, nur der Linux-Baum-Befehl, und Konfiguriere deine eigenen Parameter. Hier -X gibt XML-Ausgabe! Für mich ist das in Ordnung, und ich denke, es gibt ein Skript, um XML in JSON zu konvertieren. HINWEIS: Ich denke, https://unix.stackexchange.com/questions/90115/convert-output-of-tree-command-to-json-format/ deckt die gleiche Frage.

1

Die meisten der Linux-Maschine hat bereits Python. Alles, was Sie tun müssen, ist:

python -c 'import os, json; print json.dumps(os.listdir("/yourdirectory"))' 

Dies ist für. Verzeichnis können Sie einen beliebigen Pfad hinzufügen.

+1

Deine Antwort scheint eine zu sein Genaues Duplikat von http://stackoverflow.com/a/10234470/817632 – Olga

+0

Wie würde ich dies ändern, um auch Verzeichnisse zu folgen? – user3662307

+0

können Sie dies für verschiedene Verzeichnisse mit Python -c tun 'import os, json; print json.dumps (os.listdir ("/ mydirectory/temp")) ' –

9

Wenn Sie wissen, dass kein Dateiname enthält Zeilenumbrüche, Verwendung jq:

ls | jq -R -s -c 'split("\n")'

Kurze Erklärung der Fahnen zu jq:

  • -R behandelt die Eingabe als Zeichenfolge anstelle von JSON
  • -s verbindet alle Linien zu einem Array
  • -c erzeugt einen kompakten Ausgang.

Dies erfordert Version 1.4 oder höher von jq. Versuchen Sie dies, wenn es nicht für Sie arbeiten:

ls | jq -R '[.]' | jq -s -c 'add'

+0

Fehler: Split ist nicht definiert Split ("\ n") ^^^^^ 1 Kompilierfehler –

+0

Ich habe beide 'ls | versucht jq -R -s -c 'split ("\ n")' 'und' ls | jq -R '[.]' | jq -s -c 'hinzufügen''. Der erstere hat eine zusätzliche leere Zeichenfolge "" in das Array hinzugefügt. Letzteres ist also eine bessere Lösung. – Devy