it-swarm.com.de

Wie kann man gültigen JSON in CSV umwandeln?

Ich versuche, Informationen aus einer JSON-Datei zu extrahieren und einen Teil des Inhalts in eine CSV-Datei zu schreiben.

Hier ist ein Beispiel meines Textes

"data":{"headers":{"sender":"[email protected]"
"to":"[email protected]"
"subject":"Help with this project"
"x-received-time":"14144273245408"
"received":"from abc.com ()\r\n        by mail.mail.com with SMTP (Postfix)\r\n        for [email protected];\r\n        Mon
"from":"\"Help with this project\" <[email protected]>"
"date":"Mon, 27 Oct 2014 09:03:14 -0500"
"id":"1414427328-2345855-frank"
"to":"[email protected]"
"time":14144273245408
"subject":"Help with this project"
"fromfull":"[email protected]"

Ich möchte den Inhalt von: to, fromfull, id, subject, date abrufen und in eine csv-Datei schreiben, wobei To Spalte A ist, fromfull Spalte B ist und so weiter.

Kann jemand Hilfe anbieten? Dies ist eine JSON-Antwort.

6
BeMy Friend

Mit dem folgenden Perl-Befehl können Sie die CSV-Ausgabe erstellen, ein Terminal öffnen und Folgendes eingeben:

Perl -n0e '@a= $_ =~ /"date":(".*?").*?"id":(".*?").*?"to":"(.*?)".*?".*?"subject":(".*?").*?"fromfull":"(.*?)"/gs;  while (my @next_n = splice @a, 0, 5) { print join(q{,}, @next_n)."\n"}' inputfile.txt

Dies funktioniert auch dann, wenn Ihre Eingabedatei mehrere Überschriften enthält.

Beachten Sie, dass nur das letzte "bis" -Feld berücksichtigt wird (Ihre Kopfzeilen scheinen die Informationen zweimal bereitzustellen).

Die Befehlsausgabe:

"Mon, 27 Oct 2014 09:03:14 -0500","1414427328-2345855-frank",[email protected],"Help with this project",[email protected]
8
Sylvain Pineau

Sie können diese JSON-Datei in einer einzelnen Zeile mit jq in CSV konvertieren.

jq '.data.headers | [.sender, .to, .subject, ."x-received-time", 
.received, .from, .date, .id, .to, .subject, .fromfull] 
+ [(.time | tostring)] | join(", ")'

Nervenzusammenbruch:

  • .data.headers - Header als Objekt ausgeben
    • Wenn Daten ein Array von Headern enthalten würden, wäre dies .data[].headers
  • […string keys list…] - Zeichenfolgenwerte als Array ausgeben
  • + [(.time | tostring)] - Zeit als String ausgeben und zum Array hinzufügen
  • join(", ") - Verbinden Sie die Array-Werte mit einem Komma und einem Leerzeichen
    • Ersetzen Sie hier Ihr bevorzugtes Trennzeichen
9
Joe Harris

Da Sie mit JSON-Dateien arbeiten, können Sie sie als solche analysieren. Installieren Sie nodejs-legacy und erstellen Sie ein NodeJS-Skript wie:

#!/usr/bin/env node
// parseline.js process lines one by one
'use strict';
var readline = require('readline');
var rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
  terminal: false
});

rl.on('line', function(line){
    var obj = JSON.parse(line);
    // add the fields which you want to extract here:
    var fields = [
        obj.data.headers.to,
        obj.data.headers.subject,
        // etc.
    ];
    // print the fields, joined by a comma (CSV, duh.)
    // No escaping is done, so if the subject contains ',',
    // then you need additional post-processing.
    console.log(fields.join(','));
});

Angenommen, Sie haben eine gültige JSON-Zeichenfolge in jeder Zeile einer Datei:

node parseline.js < some.txt

Oder wenn Sie wirklich eine einzelne Datei lesen und Felder daraus analysieren möchten:

#!/usr/bin/env node
// parsefile.js - fully read file and parse some data out of it
'use strict';
var filename = process.argv[1]; // first argument
var fs = require('fs');
var text = fs.readFileSync(filename).toString();
var obj = JSON.parse(text);
// add the fields which you want to extract here:
var fields = [
    obj.data.headers.to,
    obj.data.headers.subject,
    // etc.
];
// print the fields, joined by a comma (CSV, duh.)
// No escaping is done, so if the subject contains ',',
// then you need additional post-processing.
console.log(fields.join(','));

Dann starte es mit:

node parsefile.js yourfile.json > yourfile.csv
6
Lekensteyn

Sie können jsonv von GitHub verwenden

Und dann den folgenden Befehl:

cat YOUR_JSON_FILEname | jsonv to,fromfull,id,subject,date > output.csv
1
Edward Moffett

Hier ist eine awk Implementierung:

   awk -F ":" '{gsub("\"","",$1);key=$1;sub(key " ","");gsub("\\","",$0);value[key]=$0; if ("fromfull"== key) print value["from"] ";" value["to"] ";" value["fromfull"] ";" value["id"] ";" value["subject"] ";" value["date"] ;}' jsonFile > csvFile

Dieses Skript liest die Zeile, bis es die Zeile "fromfull" gefunden hat, und gibt dann die Zeile csv aus. Daher sollte es auch mit mehreren Sequenzen funktionieren.

Das ist das Ergebnis:

  ""Help with this project" <[email protected]>";"[email protected]";"[email protected]";"1414427328-2345855-frank";"Help with this project";"Mon, 27 Oct 2014 09 03 14 -0500"
1
Lety

Hier ist ein Gawk-Skript, das ich gerade für dich geschrieben habe!

#!/usr/bin/gawk -f
BEGIN {
  FS="\""
  output=""
  nodata=1
}

/^"data"/{
  if( ! nodata )
  {
    gsub("|$","",output)
    print output
    nodata=0
  }
  output=""
}

/^"[^d][^a][^t][^a]/{
  if ( $2 == "to" || $2 == "fromfull" || $2 == "id" || $2 == "subject" || $2 == "date" )
    output=output$4"|"
}

END{
  gsub("|$","",output)
  print output
}

Es sollte auf einer Datei mit ein paar ähnlichen Einträgen funktionieren. Wenn Sie der Liste weitere Elemente hinzufügen möchten, fügen Sie diese einfach in die if-Anweisung ein. Ich habe jedoch ein Problem mit Ihrem Datensatz gefunden: die Daten. Sie enthalten Kommas, daher kann es sich nicht um eine echte CSV handeln. Stattdessen habe ich es einfach mit einem anderen Zeichen getrennt.

1
Chuck R