2013-11-24 3 views
18

Ich versuche, ein Objekt zu konvertieren, das wie folgt aussieht:Wie ein Objekt zu Arrays zuordnen, so dass es in CSV konvertiert werden kann?

{ 
    "123" : "abc", 
    "231" : "dbh", 
    "452" : "xyz" 
} 

Um csv, die wie folgt aussieht: das Kommandozeilen-Tool jq kann aber ich würde es vorziehen verwenden

"123","abc" 
"231","dbh" 
"452","xyz" 

nicht scheinen herauszufinden, wie man die Aufgabe erledigt. Ich schaffte es, die Schlüssel mit jq '. | keys' test.json zu bekommen, aber konnte nicht herausfinden, was als nächstes zu tun ist.

Das Problem ist, dass Sie ein K: v-Objekt nicht direkt in csv mit @csv konvertieren können. Es muss ein Array sein, also müssen wir zuerst in ein Array konvertieren. Wenn die Schlüssel benannt würden, wäre es einfach, aber sie sind dynamisch, also ist es nicht so einfach.

+0

Warum nicht einfach gsub ':' für ''? –

+0

google 'JSON zu csv' ... viele Ergebnisse – charlietfl

+0

gefunden in 15 Sekunden im Suchfeld oben auf der Seite..http: //stackoverflow.com/questions/8847766/how-to-convert-json-to- csv-format-und-speichern-in-einem-Variable/8924856 # 8924856 – charlietfl

Antwort

25

diesen Filter Versuchen:

to_entries[] | [.key, .value] 
  • to_entries wandelt ein Objekt auf eine Anordnung von Schlüssel/Wert-Objekte. [] zerlegt das Array zu jedem der Elemente im Array
  • dann für jedes der Elemente, verdeckt in ein Array mit dem Schlüssel und Wert.

Dies erzeugt die folgende Ausgabe:

[ 
    "123", 
    "abc" 
], 
[ 
    "231", 
    "dbh" 
], 
[ 
    "452", 
    "xyz" 
] 

Dann können Sie die @csv Filter verwenden, um die Zeilen in der CSV-Zeilen zu konvertieren.

$ echo '{"123":"abc","231":"dbh","452":"xyz"}' | jq -r 'to_entries[] | [.key, .value] | @csv' 
"123","abc" 
"231","dbh" 
"452","xyz" 
+0

Hmm. Für mich gibt dies "123", "abc" etc. usw. zurück. Jede Zeile wird zusätzlich zitiert. –

+3

Stellen Sie sicher, dass Sie dem Aufruf die Markierung '-r' hinzufügen. Sie werden die rohe Ausgabe erhalten wollen. –

+0

Danke, das habe ich übersehen. –

1

Jeff Antwort ist ein guter Ausgangspunkt ist, etwas näher an, was Sie erwarten:

cat input.json | jq 'to_entries | map([.key, .value]|join(","))' 

[ 
"123,abc", 
"231,dbh", 
"452,xyz" 
] 

Aber nicht finden einen Weg Newline verbinden mit:

cat input.json | jq 'to_entries | map([.key, .value]|join(","))|join("\n")' 

"123,abc\n231,dbh\n452,xyz" 
+0

"\ n" ist die JSON-Darstellung von newline; Um es als eine literale Newline zu sehen, verwenden Sie die Option -r Befehl-Line von jq. Im Allgemeinen ist es jedoch besser, '@ csv' zu verwenden, um CSV zu erhalten, da @csv wirklich gültige CSV-Dateien erzeugt. – peak

3

Hier ist ein Beispiel Ich habe heute Morgen damit angefangen (PagerDuty Alarme zu verarbeiten):

cat /tmp/summary.json | jq -r ' 
    .incidents 
    | map({desc: .trigger_summary_data.description, id:.id}) 
    | group_by(.desc) 
    | map(length as $len 
    | {desc:.[0].desc, length: $len}) 
    | sort_by(.length) 
    | map([.desc, .length] | @csv) 
    | join("\n") ' 

Diese Dumps ein CVS-getrennt-Dokument, das wie etwas aussieht: "[Triggered] Something annoyingly frequent",31 "[Triggered] Even more frequent alert!",35 "[No data] Stats Server is probably acting up",55

-3
onecol2txt() { 
awk 'BEGIN { RS="_end_"; FS="\n"} 
    { for (i=2; i <= NF; i++){ 
     printf "%s ",$i 
     } 
    printf "\n" 
    }' 
} 
cat jsonfile | jq -r -c '....,"_end_"' | onecol2txt 
Verwandte Themen