JSON in Bash — jq Guide & Beispiele
Nutze das kostenlose JSON Formatter & Beautifier direkt im Browser – keine Installation erforderlich.
JSON Formatter & Beautifier online testen →Wenn ein Deploy-Skript beginnt, API-Antworten zu verarbeiten oder Konfigurationsdateien in CI zu validieren, wird das Wissen, wie man JSON in Bash formatiert, schnell unverzichtbar. Die zwei Tools, die 99 % der realen Anwendungsfälle abdecken, sind jq und python3 -m json.tool — beide können JSON-Bash-Pipelines zuverlässig formatieren, mit Exit-Codes validieren und nahtlos in CI/CD-Workflows integriert werden. Für gelegentliche Inspektion ohne Terminal verarbeitet der browserbasierte JSON Formatter dies sofort. Dieser Leitfaden behandelt die jq-Installation, Pipe- und Datei-Formatierung, Validierungsfunktionen, CI/CD-Integration in GitHub Actions, Pre-Commit-Hooks, Heredoc-Muster und wann auf den Python-Stdlib-Fallback zurückgegriffen werden sollte.
- •
jq .formatiert UND validiert gleichzeitig — beendet sich mit Code 1 bei ungültigem JSON - •
jq -ein CI-Pipelines verwenden: Nicht-Null-Exit bei leerer/false/null-Ausgabe - •
jq . file.json > /dev/null && echo "valid"— validieren ohne die Ausgabe zu verändern - •
python3 -m json.toolfunktioniert auf jedem System ohne zusätzliche Installation - • Niemals
jq . f.json > f.jsonausführen — die Shell kürzt die Quelldatei, bevor jq sie liest
Was ist JSON-Formatierung in Bash?
JSON-Formatierung in Bash bedeutet, kompaktes, minifiziertes JSON in eingerückten, lesbaren Output umzuwandeln. Die zugrunde liegenden Daten bleiben unverändert — nur Leerzeichen und Zeilenumbrüche unterscheiden sich. In Skripting-Kontexten ist dies aus zwei Gründen wichtig: Lesbarkeit beim Debuggen und Validierung, wenn der Formatierer die Syntax als Nebeneffekt überprüft. Tools wie jq parsen das JSON vollständig, bevor sie es neu formatieren — ein erfolgreicher Formatierungslauf ist daher auch eine implizite Gültigkeitsprüfung. Dieses doppelte Verhalten — Formatieren und Validieren in einem Schritt — macht jq so nützlich in automatisierten Pipelines.
{"service":"payments-api","version":"2.4.1","database":{"host":"db-prod-01.internal","port":5432,"pool_size":20},"cache":{"enabled":true,"ttl":300}}{
"service": "payments-api",
"version": "2.4.1",
"database": {
"host": "db-prod-01.internal",
"port": 5432,
"pool_size": 20
},
"cache": {
"enabled": true,
"ttl": 300
}
}jq — JSON in Bash formatieren
jq ist der De-facto-Standard für die JSON-Verarbeitung in Shell-Skripten (jq 1.6+, bash 4+). Es ist ein speziell entwickelter Kommandozeilen-JSON-Prozessor, der JSON formatieren, filtern, transformieren und validieren kann. Der Identitätsfilter . gibt die Eingabe unverändert, aber formatiert aus. Wenn jq die Eingabe nicht parsen kann, beendet es sich mit Code 1 — das macht es ideal für Skripting: Formatierung und Validierung sind ein einziger Vorgang.
jq installieren
# macOS brew install jq # Debian / Ubuntu apt-get install -y jq # Fedora / RHEL / CentOS dnf install jq # Alpine (Docker-Images) apk add --no-cache jq # Überprüfen jq --version # jq-1.7.1
Aus stdin und aus einer Datei formatieren
# Inline-JSON durch jq pipen
echo '{"host":"db-prod-01.internal","port":5432}' | jq .
# Eine Datei direkt formatieren (gibt auf stdout aus)
jq . config/feature-flags.json
# Mit 4-Leerzeichen-Einrückung formatieren
jq --indent 4 . config/feature-flags.json
# Mit Tabulatoren statt Leerzeichen formatieren
jq --tab . config/feature-flags.jsonFormatierte Ausgabe in eine Datei schreiben
# Formatierte Ausgabe speichern (NICHT zurück in dieselbe Datei umleiten) jq . compact.json > formatted.json # Kompakt (minifizieren) — Umkehrung der Formatierung jq -c . formatted.json
jq beendet sich mit Code 1 bei ungültigem JSON, Code 0 bei Erfolg und Code 5 bei Verwendungsfehlern. Dies in if-Anweisungen und || exit 1 Guards in Skripten verwenden.Schlüssel sortieren und Farbe entfernen
# Alle Schlüssel alphabetisch sortieren (nützlich für deterministische Diffs) jq --sort-keys . config/app-config.json # Farbausgabe deaktivieren beim Schreiben in eine Log-Datei jq --monochrome-output . response.json >> deploy.log
jq-Optionsreferenz
Die am häufigsten verwendeten jq-Flags für Formatierungs- und Validierungs-Workflows:
JSON in einem Bash-Skript validieren
Validierung und Formatierung sind bei jq derselbe Vorgang — es parst, bevor es ausgibt. stdout nach /dev/null umleiten, wenn nur der Exit-Code ohne die formatierte Ausgabe benötigt wird. Das folgende Muster ist in Deploy-Skripten, Pre-Commit-Hooks und CI-Pipelines wiederverwendbar. Bei der Incident-Response ist das Erste bei einer unbekannten API-Payload, diese durch jq zu pipen — es verwandelt eine Wand aus minifiziertem JSON in etwas Lesbares und Debuggbares.
Wiederverwendbare Validierungsfunktion
validate_json() {
local file="$1"
if jq . "$file" > /dev/null 2>&1; then
echo "✓ Gültiges JSON: $file"
return 0
else
echo "✗ Ungültiges JSON: $file" >&2
return 1
fi
}Deploy bei ungültiger Konfiguration abbrechen
CONFIG="infra/k8s/app-config.json"
validate_json "$CONFIG" || { echo "Deploy abgebrochen: ungültige Konfiguration" >&2; exit 1; }Alle JSON-Dateien in einem Verzeichnis validieren
find ./config -name "*.json" | while read -r f; do jq . "$f" > /dev/null 2>&1 || echo "UNGÜLTIG: $f" done
-e / --exit-status geht weiter: es beendet sich auch mit Code 1, wenn die Ausgabe false oder null ist. Damit lässt sich sicherstellen, dass ein bestimmtes Feld truthy ist: jq -e '.feature_flags.new_checkout' config.json.JSON aus Dateien und API-Antworten formatieren
Zwei häufige JSON-Quellen in Shell-Skripten sind Dateien auf der Festplatte und HTTP-API-Antworten über curl. Jede hat ein leicht unterschiedliches Handling-Muster. Bei Dateien ist die wichtigste Überlegung das sichere direkte Bearbeiten. Bei API-Antworten ist der entscheidende Punkt, den Fortschrittsbalken von curl zu unterdrücken, damit dieser nicht die jq-Eingabe korrumpiert.
Sicheres direktes Formatieren einer Datei
# Sicher formatieren und überschreiben mit einer temporären Datei tmp=$(mktemp) jq --indent 2 . config/feature-flags.json > "$tmp" && mv "$tmp" config/feature-flags.json echo "config/feature-flags.json formatiert"
Eine curl-API-Antwort formatieren
# Deploy-Status von der API formatieren DEPLOY_ID="dep_8f3a2b9c" curl -s \ -H "Authorization: Bearer $DEPLOY_API_TOKEN" \ "https://api.deployments.internal/v1/deploys/$DEPLOY_ID" \ | jq --indent 2 .
Gleichzeitig formatieren und filtern
# Formatiert + nur Fehler von einem Monitoring-Endpunkt abrufen
curl -s "https://monitoring.internal/api/events?level=error&limit=10" \
| jq '[.events[] | {id, message, timestamp, service}]' \
|| { echo "Fehler beim Abrufen oder Parsen der Events" >&2; exit 1; }Das Muster || { ... } ist hier entscheidend. Ohne es wird ein fehlgeschlagener curl-Aufruf oder eine fehlerhafte API-Antwort lautlos durchgereicht, und der nächste Schritt im Skript arbeitet mit leeren oder unvollständigen Daten. Wenn komplexe verschachtelte Antworten ohne einen vorher geschriebenen Filterausdruck inspiziert werden müssen, ermöglicht der browserbasierte JSON Formatter das Einfügen der Roh-Antwort und die interaktive Navigation im Baum.
JSON in CI/CD-Pipelines formatieren
CI ist der Ort, wo JSON-Validierungs-Gates am wichtigsten sind — eine fehlerhafte Konfiguration, die die Produktion erreicht, ist wesentlich schwieriger zurückzurollen als ein Pipeline-Fehler. Die folgenden Muster werden in produktiven SRE-Workflows eingesetzt, um Konfigurationsfehler zu erkennen, bevor sie jemals einen Deployment-Slot erreichen.
GitHub Actions — alle JSON-Konfigurationen validieren
- name: JSON-Konfigurationen validieren
run: |
echo "JSON-Konfigurationsdateien werden validiert..."
find . -name "*.json" -not -path "*/node_modules/*" | while read -r f; do
if ! jq . "$f" > /dev/null 2>&1; then
echo "::error file=$f::Ungültige JSON-Syntax"
exit 1
fi
done
echo "Alle JSON-Dateien sind gültig"Pre-Commit-Hook — gestagte JSON-Dateien validieren
#!/usr/bin/env bash
set -euo pipefail
STAGED=$(git diff --cached --name-only --diff-filter=ACM | grep '\.json$' || true)
[ -z "$STAGED" ] && exit 0
for f in $STAGED; do
jq . "$f" > /dev/null 2>&1 || { echo "Ungültiges JSON: $f"; exit 1; }
done
echo "JSON-Validierung bestanden"scripts/validate-json.sh speichern, mit chmod +x scripts/validate-json.sh ausführbar machen, dann verknüpfen: ln -s ../../scripts/validate-json.sh .git/hooks/pre-commit.JSON-Variablen und Heredocs in Bash formatieren
Shell-Skripte bauen JSON-Payloads häufig dynamisch auf — aus Umgebungsvariablen, Git-Metadaten oder berechneten Werten. Das sicherste Muster ist jq -n --arg / --argjson statt String-Interpolation, die sofort bricht, wenn ein Wert ein Anführungszeichen oder einen Zeilenumbruch enthält. Variablen beim Pipen zu jq immer in doppelte Anführungszeichen setzen, um Word-Splitting bei Leerzeichen im JSON zu verhindern.
Eine gespeicherte API-Antwortvariable formatieren
# "$API_RESPONSE" immer in Anführungszeichen setzen — Leerzeichen im JSON würden eine nicht-quotierte Expansion brechen echo "$API_RESPONSE" | jq --indent 2 .
Payload mit jq -n erstellen und formatieren
payload=$(jq -n \
--arg env "production" \
--arg version "$(git describe --tags)" \
--argjson replicas 3 \
'{environment: $env, version: $version, replicas: $replicas}')
# Den erstellten Payload inspizieren
echo "$payload" | jq .
# An eine API senden
curl -s -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $DEPLOY_API_TOKEN" \
-d "$payload" \
"https://api.deployments.internal/v1/deploys"--arg bindet immer einen String-Wert. --argjson parst den Wert zuerst als JSON, sodass Zahlen, Boolesche Werte, Arrays und Objekte übergeben werden können, ohne sie im Filterausdruck zu quotieren.JSON in Bash ohne jq formatieren
Wenn jq nicht verfügbar ist — minimale Docker-Images, gesperrte CI-Runner oder Systeme, auf denen keine Pakete installiert werden können — bietet das integrierte json.tool-Modul von Python dieselbe Kernfunktionalität. Es ist Teil der Python-Standardbibliothek; wenn Python 3 installiert ist, funktioniert es ohne zusätzliche Abhängigkeiten.
# Aus einer Datei formatieren python3 -m json.tool config.json # Einrückungsbreite steuern python3 -m json.tool --indent 2 config.json # Schlüssel alphabetisch sortieren python3 -m json.tool --sort-keys config.json # Aus stdin formatieren (z.B. von curl gepipt) curl -s https://api.deployments.internal/v1/status | python3 -m json.tool
python3 -m json.tool ist strenger als jq: es lehnt abschließende Kommas, Kommentare und JSON5-Erweiterungen ab. Diese Striktheit ist für die Validierung von Produktionskonfigurationen wünschenswert, kann aber ein Hindernis sein, wenn mit nachsichtigem JSON von Drittanbieter-Tools gearbeitet wird. Außerdem wird keine farbige Ausgabe erzeugt, was die Terminal-Inspektion weniger ergonomisch macht als jq für den interaktiven Gebrauch.# Validierung mit Exit-Code (gleiche Semantik wie jq)
python3 -m json.tool config.json > /dev/null && echo "gültig" || echo "ungültig"
# Inline-String-Validierung
echo '{"service":"payments-api","healthy":true}' | python3 -m json.tool > /dev/null
echo "Exit-Code: $?" # 0 = gültigTerminal-Ausgabe mit Syntax-Highlighting
jq coloriert seine Ausgabe standardmäßig — Schlüssel in Blau, Zeichenketten in Grün, Zahlen in Weiß. Wenn vollständiges JSON-Syntax-Highlighting in einem scrollbaren Pager benötigt wird oder beim Debuggen großer verschachtelter Antworten in einer Terminal-Sitzung, bietet bat die ergonomischste Erfahrung. Beide sind nützlich zum Debuggen und zur interaktiven Inspektion; keines sollte beim Schreiben in Dateien oder API-Antworten verwendet werden.
bat installieren
# macOS brew install bat # Debian / Ubuntu (Binary kann batcat heißen — ggf. Alias erstellen) apt-get install -y bat # alias bat=batcat # bei Bedarf zu ~/.bashrc hinzufügen # Überprüfen bat --version # bat 0.24.0
JSON-Dateien mit Syntax-Highlighting anzeigen
# Syntax-hervorgehobenes JSON im Pager (q zum Beenden drücken) bat config/app-config.json # Paging deaktivieren — direkt im Terminal ausgeben bat --paging=never config/app-config.json # jq-Ausgabe durch bat für farbige Inspektion pipen jq '.database' infra/app-config.json | bat --language=json --paging=never
Colorierte jq-Ausgabe in einem scrollbaren Pager
# -C erzwingt Farbe auch wenn stdout kein TTY ist (z.B. beim Pipen zu less) jq -C . logs/deploy-response.json | less -R
bat / jq -C) nur für Terminal-Inspektion und Debugging verwenden. ANSI-Farbcodes vor dem Schreiben in Log-Dateien oder beim Pipen zu anderen Tools entfernen — dafür jq -M . (--monochrome-output) oder bat --plain verwenden.Mit großen JSON-Dateien in Bash arbeiten
Wenn eine JSON-Datei 50–100 MB überschreitet, kann das Laden in den Speicher mit jqs Standard-Modus langsam sein oder auf speicherbeschränkten Hosts (z.B. Docker-Container mit einem 512-MB-Limit) einen OOM auslösen. jq --stream gibt Pfad/Wert-Paare inkrementell aus, während es liest, ohne das gesamte Dokument zu puffern. Für NDJSON (ein JSON-Objekt pro Zeile) bietet jq einen effizienteren nativen Ansatz.
Große JSON-Datei mit jq --stream streamen
# --stream gibt [Pfad, Skalar]-Paare aus, während jq die Eingabe liest # Alle "status"-Felder aus einem großen Log-Archiv extrahieren, ohne es vollständig zu laden jq -c --stream 'if length == 2 and (.[0][-1] == "status") then .[1] else empty end' logs/archive-2026-03.json
NDJSON / JSON Lines — ein Objekt pro Zeile verarbeiten
# NDJSON: ein JSON-Objekt pro Zeile — häufig in Kafka-Exports, Fluentd und Logstash
# -R liest Rohzeilen; fromjson? überspringt Zeilen, die kein gültiges JSON sind
jq -c -R 'fromjson? | {id: .request_id, status: .http_status, latency: .duration_ms}' logs/access-2026-03-13.ndjson > logs/summary.ndjson# Shell-Schleifen-Alternative — nützlich wenn zeilenweises Fehlerhandling benötigt wird
while IFS= read -r line; do
echo "$line" | jq -c '{id: .request_id, status: .http_status}' 2>/dev/null || echo "ÜBERSPRUNGEN: fehlerhafte Zeile" >&2
done < logs/access-2026-03-13.ndjsonjq . file.json zu --stream wechseln, wenn die Datei größer als 50–100 MB ist oder wenn der Prozess in einem Container mit einem Speicherlimit läuft. Für NDJSON-Pipelines jq -R 'fromjson?' einer Shell-while read-Schleife vorziehen — es ist deutlich schneller, da kein Subshell pro Zeile gestartet wird.Häufige Fehler
Problem: Die Shell öffnet und kürzt die Ausgabedatei, bevor jq die Eingabe liest. Wenn Quelle und Ziel denselben Pfad haben, liest jq eine leere Datei.
Lösung: Zuerst in eine temporäre mktemp-Datei schreiben, dann das Original atomar mit mv ersetzen.
jq --indent 2 . settings.json > settings.json
tmp=$(mktemp) && jq --indent 2 . settings.json > "$tmp" && mv "$tmp" settings.json
Problem: Ohne Fehlerbehandlung setzt das Skript lautlos mit einer leeren oder fehlenden formatierten Datei fort, wenn JSON ungültig ist — nachfolgende Schritte scheitern dann mit verwirrenden Fehlern.
Lösung: Nach jedem jq-Aufruf, der Ausgaben für einen späteren Schritt erzeugt, || { echo '...' >&2; exit 1; } hinzufügen.
jq . response.json > formatted.json
jq . response.json > formatted.json || { echo "Ungültiges JSON in response.json" >&2; exit 1; }Problem: curl gibt standardmäßig einen Fortschrittsbalken auf stderr aus. Wenn stderr mit stdout zusammengeführt wird (z.B. in Subshells oder Log-Captures), erscheint der Fortschrittsbalkentext in jqs Eingabe und verursacht einen Parse-Fehler.
Lösung: Immer -s (silent) an curl übergeben, wenn zu jq gepipt wird. -v oder --fail-with-body separat verwenden, wenn diagnostische Ausgabe benötigt wird.
curl https://api.payments.internal/config | jq .
curl -s https://api.payments.internal/config | jq .
Problem: Das Flag -r / --raw-output entfernt JSON-Zeichenkettenanführungszeichen von Top-Level-String-Werten — es formatiert keine Objekte oder Arrays. -r . an ein Objekt zu übergeben erzeugt dasselbe kompakte Objekt, nicht eingerückten Output.
Lösung: jq . (ohne -r Flag) für die Formatierung verwenden. -r für das Extrahieren von Klartextwerten reservieren, z.B. jq -r '.version' config.json.
jq -r . config.json
jq . config.json
jq vs python3 vs json_pp — Schneller Vergleich
Die Wahl zwischen Tools hängt davon ab, was in der Umgebung verfügbar ist und was über die grundlegende Formatierung hinaus benötigt wird:
Für die meisten Bash-Scripting- und CI/CD-Aufgaben ist jq die richtige Standardwahl — es validiert, formatiert, filtert und bietet zuverlässige Exit-Codes in einer einzigen Binärdatei ohne Laufzeitabhängigkeit. Auf python3 -m json.tool zurückgreifen, wenn keine zusätzlichen Pakete installiert werden können und Python bereits vorhanden ist.
Häufig Gestellte Fragen
Wie formatiere ich eine JSON-Datei direkt in Bash?
Die jq-Ausgabe niemals zurück in dieselbe Datei umleiten — die Shell kürzt die Datei, bevor jq sie liest. Stattdessen zuerst in eine temporäre Datei schreiben, dann die Original-Datei atomar mit mv ersetzen.
tmp=$(mktemp) jq --indent 2 . config/app-config.json > "$tmp" && mv "$tmp" config/app-config.json echo "Erfolgreich direkt formatiert"
Wie validiere ich JSON in einem Bash-Skript und breche bei einem Fehler ab?
Die Datei per Pipe oder direkt an jq übergeben und stdout nach /dev/null umleiten. Mit || den Nicht-Null-Exit abfangen und das Skript abbrechen. jq beendet sich mit Code 1 bei jedem Parse-Fehler, was es für CI-Gates zuverlässig macht.
validate_json() {
local file="$1"
if jq . "$file" > /dev/null 2>&1; then
echo "✓ Gültiges JSON: $file"
return 0
else
echo "✗ Ungültiges JSON: $file" >&2
return 1
fi
}
validate_json infra/k8s/app-config.json || exit 1Wie formatiere ich JSON in Bash ohne jq zu installieren?
Das integrierte json.tool-Modul von Python3 verwenden — es ist in jeder Standard-Python-Installation enthalten und erzeugt korrekt eingerückten Output mit denselben Exit-Code-Semantiken wie jq.
# Aus einer Datei formatieren python3 -m json.tool config.json # Aus stdin formatieren (z.B. eine curl-Antwort) curl -s https://api.internal/status | python3 -m json.tool --indent 2
Wie formatiere ich eine curl-Antwort als JSON in Bash?
Immer -s (silent) an curl übergeben, damit Fortschrittsbalken die jq-Eingabe nicht korrumpieren. Die stdout-Ausgabe von curl direkt in jq pipen.
DEPLOY_ID="dep_8f3a2b9c" curl -s \ -H "Authorization: Bearer $DEPLOY_API_TOKEN" \ "https://api.deployments.internal/v1/deploys/$DEPLOY_ID" \ | jq --indent 2 .
Wie formatiere ich nur einen Teil einer JSON-Datei mit jq?
Einen jq-Pfadausdruck anstelle des Identitätsfilters (.) verwenden, um ein verschachteltes Objekt oder Array zu extrahieren und zu formatieren. Das Ergebnis ist selbst formatiertes JSON.
# Nur den Datenbank-Konfigurationsblock formatieren
jq --indent 2 '.database' infra/app-config.json
# Formatieren + Events-Array auf Fehler-Level filtern
jq '[.events[] | select(.level == "error") | {id, message, service}]' events.jsonWelchen Exit-Code gibt jq bei ungültigem JSON zurück?
jq beendet sich mit Code 1 bei jedem Parse-Fehler und auch wenn das Flag -e / --exit-status gesetzt ist und die Ausgabe false oder null ist. Exit-Code 0 bedeutet, dass gültiges JSON geparst wurde und eine wahre Ausgabe erzeugt hat. Exit-Code 5 bedeutet, dass ein Verwendungsfehler aufgetreten ist.
# Exit-Code direkt testen
echo '{"ok":true}' | jq . > /dev/null 2>&1; echo "exit: $?" # exit: 0
echo '{bad json}' | jq . > /dev/null 2>&1; echo "exit: $?" # exit: 1
# -e Flag: exit 1 wenn Ausgabe false/null ist
echo 'null' | jq -e . > /dev/null 2>&1; echo "exit: $?" # exit: 1Verwandte Tools
Browserbasierte Alternativen und Ergänzungen zur Bash-JSON-Formatierung — nützlich, wenn eine visuelle Oberfläche, ein teilbarer Link benötigt wird oder außerhalb eines Terminals gearbeitet wird:
Nadia is a site reliability engineer who lives in the terminal. She writes Bash scripts that process logs, transform data, and orchestrate infrastructure across fleets of servers. She is a heavy user of jq, awk, and sed and writes about shell one-liners, text processing pipelines, data serialisation from the command line, and the practical Bash patterns that SREs reach for when speed matters more than elegance.
Erik is a DevOps engineer who has spent years writing and maintaining the shell scripts that hold CI/CD pipelines together. He writes about Bash best practices, portable POSIX shell, encoding and decoding in shell scripts, secret management from the command line, and the patterns that separate reliable automation scripts from brittle ones. He is a strong believer in making shell scripts readable and testable with tools like bats-core.