Befehl zum Entfernen eines Teils der JSON-Daten aus jeder Zeile?

Befehl zum Entfernen eines Teils der JSON-Daten aus jeder Zeile?

Ich habe test.jsoneine Datei mit unterschiedlich langen Zeilen. Einige fiktive Beispiele:

{ a: 123, b: sd, c: x45, d: 1, e: '' }
{ a: 5, b: bfgg, c: x4c, d: 31, e: '' }

Ich möchte den gesamten Teilstring nach dem -Teil ausschneiden dund nur für jede Zeile Folgendes zurückbekommen:

{ a: 123, b: sd, c: x45 }
{ a: 5, b: bfgg, c: x4c }

ich fandHiereine ähnliche Frage und habe versucht, mein Problem darauf abzustimmen:

echo test.json |  sed 's/. d:/' > newtest.json

Ich muss es für die ganze Datei tun, nicht nur für eine Zeile.

Antwort1

Wenn Sie häufig JSON über die Befehlszeile transformieren, lohnt es sich, sich das Tool „jq“ zu besorgen und zu lernen, wie es verwendet wird.

http://stedolan.github.io/jq/

Die obigen Antworten zeigen zwar, dass Sie minimale Transformationen durchführen können, ohne das JSON tatsächlich zu analysieren. Letztendlich werden Sie jedoch entweder einen fehlerhaften JSON-Parser über reguläre Ausdrücke neu erfinden oder wieder zum nativen JSON-Parser in der Sprache Ihrer Wahl zurückkehren.

jq ist schnell, einfach zu verwenden und ein sehr praktisches Werkzeug für Ihren Werkzeugkasten.

BWT, Ihre Testdaten sind ungültiges JSON, was die oben genannten Lösungen erschwert. Wenn Sie es beheben,

{ "a":123 , "b": "sd", "c": "x45", "d": 1, "e": "" }
{ "a":5 , "b": "bfgg", "c": "x4c", "d": 31, "e": "" }

Dann wird dieser JQ-Befehl tun, was Sie wollen

 jq -c '{a,b,c}' test.json

{"a":123,"b":"sd","c":"x45"}
{"a":5,"b":"bfgg","c":"x4c"}

Antwort2

sed '/d:/s/, d:[^}]*/ /' test.json

Es durchsucht die gesamte Datei und entfernt in jeder Zeile d:alle , d:.*Teile bis zum }Symbol ( }das Symbol bleibt in der Zeile).

Antwort3

Die beste Lösung für dieses Problem bietet wahrscheinlich die Antwort von @Rush. sedSie können es aber auch folgendermaßen erreichen awk:

$ awk -F ', d.* ' '{print $1, $2}' file.txt 
{ a: 123, b: sd, c: x45 }
{ a: 5, b: bfgg, c: x4c }

Das Obige verwendet awkzum Aufteilen der Daten auf , d.*. Dadurch werden zwei Datenfelder erzeugt, $1die $2die Daten enthalten, die sich aus der Aufteilung der Zeichenfolgen durch AWK ergeben.

Antwort4

Angenommen, Sie haben eine gültige JSON-Datei mit einer Reihe von Objekten, wie

{"a":123,"b":"sd","c":"x45","d":1,"e":"''"}
{"a":5,"b":"bfgg","c":"x4c","d":31,"e":"''"}

oder das Äquivalent

{
  "a": 123,
  "b": "sd",
  "c": "x45",
  "d": 1,
  "e": "''"
}
{
  "a": 5,
  "b": "bfgg",
  "c": "x4c",
  "d": 31,
  "e": "''"
}

und Sie möchten die Schlüssel dund eaus jedem Objekt entfernen.

Verwenden von jq, Löschen jeweils eines Schlüssels:

jq -c 'del(.d) | del(.e)' file.json

Beide Schlüssel auf einmal löschen:

jq -c 'del(.d, .e)' file.json

Das Ergebnis von beidem wäre

{"a":123,"b":"sd","c":"x45"}
{"a":5,"b":"bfgg","c":"x4c"}

Eine dritte Möglichkeit, bei der die eigentlichen Schlüssel nicht namentlich erwähnt werden, besteht darin, die Objekte mit in Listen von „Einträgen“ umzuwandeln to_entries, dann die letzten beiden Einträge zu löschen und die Liste wieder in ein geändertes Objekt umzuwandeln:

jq -c 'to_entries | del(.[-2:]) | from_entries' file.json

Dies entspricht am ehesten dem, was der Fragetext vorschlägt, und das Ergebnis hängt von der Reihenfolge der Schlüssel im Objekt ab.

verwandte Informationen