JSON auf der Kommandozeile formatieren: jq, Python und PowerShell

Am schnellsten formatierst du JSON in der Shell mit jq . oder mit python3 -m json.tool. Beide lesen aus einer Datei oder aus einer Pipe und geben lesbar eingerückten Text aus. Unter Windows bietet PowerShell mit ConvertFrom-Json | ConvertTo-Json dasselbe, hat aber einen Fallstrick bei verschachtelten Daten. Alle vier Wege unten sind kurz und lassen sich in Skripte einbauen.

Wenn du nur ein einzelnes Stück JSON prüfen willst, geht es ohne Installation im JSON-Formatierer. Er arbeitet vollständig lokal im Browser und sendet nichts an einen Server.

Als Beispiel dient diese Datei daten.json:

{"name":"Ada","tags":["a","b"],"preis":1.50,"adresse":{"stadt":"Köln","geo":{"punkt":{"lat":50.94}}}}

jq: der Standard für Pretty Print

jq ist ein eigenes Kommandozeilenwerkzeug für JSON (über den Paketmanager installierbar, etwa brew install jq oder apt install jq). Der Filter . gibt die Eingabe unverändert zurück, nur formatiert:

jq . daten.json
cat daten.json | jq .
curl -s https://example.com/api | jq .

Wichtige Optionen für den jq-Pretty-Print:

jq -c . daten.json          # kompakt: alles in einer Zeile
jq --indent 4 . daten.json  # vier Leerzeichen statt zwei
jq --tab . daten.json       # Tabs statt Leerzeichen
jq -S . daten.json          # Schlüssel alphabetisch sortieren
jq -r '.name' daten.json    # Rohtext ohne Anführungszeichen
  • -c (compact) eignet sich zum Minifizieren, siehe auch JSON minifizieren.
  • --indent n akzeptiert Werte von 0 bis 7. Bei --indent 0 ist die Ausgabe wie bei -c.
  • -S sortiert Objektschlüssel rekursiv. Das ist praktisch für Diffs, ändert aber die Reihenfolge der Daten.

Bei ungültigem JSON bricht jq mit einer Fehlermeldung und Exit-Code ungleich 0 ab. Die Position nennt es nur grob; für die genaue Stelle hilft der JSON-Formatierer oder der Ratgeber JSON-Fehler finden und beheben.

Python: json.tool

Python bringt das Modul json.tool mit, ohne dass du etwas installieren musst. Das ist die Antwort auf „json formatieren python“ in der Shell:

python3 -m json.tool daten.json
python3 -m json.tool daten.json formatiert.json   # in Datei schreiben
cat daten.json | python3 -m json.tool

Weitere Optionen:

python3 -m json.tool --indent 2 daten.json
python3 -m json.tool --sort-keys daten.json
python3 -m json.tool --no-ensure-ascii daten.json
python3 -m json.tool --compact daten.json
python3 -m json.tool --tab daten.json

Die Version spielt eine Rolle:

  • --sort-keys gibt es seit Python 3.5.
  • --indent, --tab, --compact, --no-indent und --no-ensure-ascii kamen mit Python 3.9. Auf älteren Versionen meldet json.tool bei diesen Optionen einen Fehler.
  • Ohne Option rückt json.tool mit vier Leerzeichen ein.

Wichtig ist --no-ensure-ascii. Ohne diese Option schreibt Python alle Nicht-ASCII-Zeichen als Escape-Sequenz: Aus Köln wird K\u00f6ln. Das ist gültiges JSON, aber schlecht lesbar.

Innerhalb eines Skripts nutzt du dieselben Parameter direkt:

import json

with open("daten.json", encoding="utf-8") as f:
    daten = json.load(f)

print(json.dumps(daten, indent=2, ensure_ascii=False, sort_keys=True))

PowerShell: ConvertFrom-Json und ConvertTo-Json

In PowerShell liest du die Datei ein, wandelst sie in ein Objekt um und gibst sie wieder als JSON aus:

Get-Content .\daten.json -Raw | ConvertFrom-Json | ConvertTo-Json -Depth 10

-Raw liest die Datei als einen einzigen String. Ohne -Raw bekommt ConvertFrom-Json zeilenweise Eingaben, was bei mehrzeiligem JSON zu Fehlern führen kann.

Der Tiefen-Fallstrick: ConvertTo-Json hat standardmäßig -Depth 2. Tiefer verschachtelte Objekte werden nicht mehr aufgelöst, sondern als Text des .NET-Objekts ausgegeben. Ohne -Depth sieht das Ergebnis für die Beispieldatei in PowerShell 7 so aus:

{
  "name": "Ada",
  "tags": [
    "a",
    "b"
  ],
  "preis": 1.5,
  "adresse": {
    "stadt": "Köln",
    "geo": {
      "punkt": "@{lat=50.94}"
    }
  }
}

Statt des Objekts punkt steht ein Text wie @{lat=50.94} in der Ausgabe. Die Daten sind dann stillschweigend verfälscht. PowerShell 7.1 und neuer geben dabei eine Warnung aus, Windows PowerShell 5.1 nicht. Und nicht in jedem Skript fällt die Warnung auf. Setze -Depth deshalb immer ausdrücklich, etwa auf 10 oder höher.

Weitere Optionen:

... | ConvertTo-Json -Depth 10 -Compress                  # eine Zeile
... | ConvertTo-Json -Depth 10 | Set-Content out.json -Encoding utf8

In Windows PowerShell 5.1 schreibt -Encoding utf8 ein BOM an den Dateianfang, in PowerShell 7 nicht (siehe BOM in JSON).

Die Einrückung kannst du nicht einstellen. Die Ausgabe von Windows PowerShell 5.1 und PowerShell 7 unterscheidet sich zudem im Layout, etwa bei der Einrückung und den Leerzeichen nach dem Doppelpunkt. Das Ergebnis ist in beiden Fällen gültiges JSON.

Node.js als Einzeiler

Wenn Node.js ohnehin installiert ist, brauchst du kein weiteres Werkzeug:

node -e 'console.log(JSON.stringify(JSON.parse(require("fs").readFileSync(0, "utf8")), null, 2))' < daten.json

readFileSync(0) liest von der Standardeingabe, JSON.stringify(..., null, 2) rückt mit zwei Leerzeichen ein. Für die kompakte Form lässt du null, 2 weg. Mit JSON.parse wird die Datei nebenbei auf Gültigkeit geprüft. Node ist dabei am stärksten verlustbehaftet, siehe nächster Abschnitt.

Was beim Formatieren verloren gehen kann

Alle diese Werkzeuge parsen das JSON und schreiben es neu. Dabei kann sich der Inhalt ändern. Ein Test mit {"b":1.0,"x":1e2,"n":12345678901234567890}:

Werkzeug 1.0 1e2 12345678901234567890
jq 1.7 1.0 1E+2 unverändert
python3 -m json.tool 1.0 100.0 unverändert
Node.js (JSON.parse) 1 100 12345678901234567000
  • Zahlen: Node.js rechnet mit 64-Bit-Fließkommazahlen und rundet große Ganzzahlen. Bei jq hängt das Verhalten von der Version ab; ältere Versionen als 1.7 wandeln Zahlen intern in Fließkommazahlen um. Mehr dazu im Ratgeber Große Zahlen in JSON.
  • Doppelte Schlüssel: {"a":1,"a":2} wird von jq und json.tool zu {"a":2}. Der erste Wert verschwindet ohne Warnung.
  • Schlüsselreihenfolge: bleibt bei jq und Python ohne -S bzw. --sort-keys erhalten.
  • Nicht-ASCII-Zeichen: json.tool maskiert sie ohne --no-ensure-ascii.

Brauchst du die Daten Zeichen für Zeichen unverändert, etwa bei Zahlen mit vielen Stellen oder bewusst doppelten Schlüsseln, nutze den JSON-Formatierer. Er arbeitet verlustfrei: Zahlenschreibweisen, Schlüsselreihenfolge und doppelte Schlüssel bleiben erhalten.

Kurz gesagt

  • jq . formatiert, jq -c . minifiziert, --indent n, --tab und -S steuern Einrückung und Sortierung.
  • python3 -m json.tool braucht keine Installation. Ab Python 3.9 gibt es --indent, --tab, --compact und --no-ensure-ascii; --sort-keys gibt es länger.
  • In PowerShell immer ConvertTo-Json -Depth setzen, sonst werden Daten ab der dritten Ebene verfälscht.
  • Parsen und Neuschreiben kann Zahlen runden und doppelte Schlüssel entfernen. Für verlustfreies Formatieren eignet sich der JSON-Formatierer.

Weiterlesen: JSON im Editor formatieren, JSON minifizieren, Große Zahlen in JSON.