JSON formatteren in Bash met jq – Complete Gids
Gebruik de gratis JSON Formatter & Beautifier direct in je browser — geen installatie nodig.
JSON Formatter & Beautifier online uitproberen →Wanneer een deploy-script begint met het verwerken van API-responses of het valideren van configuratiebestanden in CI, wordt het kennen van hoe je JSON in bash formatteert snel essentieel. De twee tools die 99% van de echte gevallen dekken zijn jq en python3 -m json.tool — beide kunnen JSON-bash-pipelines betrouwbaar formatteren, valideren met afsluitcodes, en schoon integreren in CI/CD-workflows. Voor eenmalige inspectie zonder terminal verwerkt de browsergebaseerde JSON Formatter het direct. Deze gids behandelt jq-installatie, pipe- en bestandsopmaak, validatiefuncties, CI/CD-integratie in GitHub Actions, pre-commit hooks, heredoc-patronen en wanneer te terugvallen op de Python stdlib.
- •
jq .formatteert EN valideert tegelijkertijd — sluit af met code 1 bij ongeldige JSON - • Gebruik
jq -ein CI-pipelines: niet-nul afsluit bij lege/false/null uitvoer - •
jq . file.json > /dev/null && echo "valid"— valideren zonder de uitvoer te wijzigen - •
python3 -m json.toolwerkt op elk systeem zonder extra installatie - • Doe nooit
jq . f.json > f.json— shell kapt het bronbestand af voordat jq het leest
Wat is JSON-opmaak in Bash?
JSON-opmaak in bash betekent het omzetten van compacte, geminificeerde JSON naar ingesprongen, leesbare uitvoer. De onderliggende gegevens zijn ongewijzigd — alleen de witruimte en regelafbrekingen verschillen. In scriptingcontexten is dit om twee redenen belangrijk: leesbaarheid bij het debuggen, en validatie wanneer de formatter de syntaxis als neveneffect controleert. Tools zoals jq parseren de JSON volledig voordat ze deze opnieuw formatteren, wat betekent dat een succesvolle opmaakrun ook een impliciete geldigheidscontrole is. Dat dubbele gedrag — formatteren en valideren in één stap — maakt jq zo nuttig in geautomatiseerde 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 formatteren in Bash
jq is de de-facto standaard voor JSON-verwerking in shellscripts (jq 1.6+, bash 4+). Het is een speciaal gebouwde command-line JSON-processor die JSON kan formatteren, filteren, transformeren en valideren. Het identiteitsfilter . geeft de invoer ongewijzigd maar geformatteerd terug. Wanneer jq de invoer niet kan parseren, sluit het af met code 1 — dit maakt het ideaal voor scripting: formatteren en valideren zijn één enkele operatie.
jq installeren
# 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 # Verifiëren jq --version # jq-1.7.1
Formatteren vanuit stdin en vanuit een bestand
# Inline JSON door jq pipen
echo '{"host":"db-prod-01.internal","port":5432}' | jq .
# Een bestand direct formatteren (drukt af naar stdout)
jq . config/feature-flags.json
# Formatteren met 4-spatie-inspringing
jq --indent 4 . config/feature-flags.json
# Formatteren met tabs in plaats van spaties
jq --tab . config/feature-flags.jsonGeformatteerde uitvoer naar een bestand schrijven
# Geformatteerde uitvoer opslaan (NIET terugsturen naar hetzelfde bestand) jq . compact.json > formatted.json # Compact (minificeren) — omgekeerde van formatteren jq -c . formatted.json
jq sluit af met code 1 bij ongeldige JSON, code 0 bij succes, en code 5 bij gebruiksfouten. Gebruik dit in if-statements en || exit 1 bewakers door uw scripts heen.Sleutels sorteren en kleur verwijderen
# Alle sleutels alfabetisch sorteren (nuttig voor deterministische diffs) jq --sort-keys . config/app-config.json # Kleuruitvoer uitschakelen bij schrijven naar een logbestand jq --monochrome-output . response.json >> deploy.log
jq Opties Referentie
De meest gebruikte jq-vlaggen voor opmaak- en validatieworkflows:
JSON valideren in een Bash-script
Validatie en opmaak zijn dezelfde bewerking in jq — het parseert voordat het afdrukt. Leid stdout om naar /dev/null wanneer alleen de afsluitcode nodig is zonder de geformatteerde uitvoer. Het onderstaande patroon is herbruikbaar in deploy-scripts, pre-commit hooks en CI-pipelines. Bij incidentrespons is het eerste wat ik doe met een onbekende API-payload het doorsluizen naar jq — het verandert een muur van geminificeerde JSON in iets dat ik daadwerkelijk kan lezen en debuggen.
Herbruikbare validatiefunctie
validate_json() {
local file="$1"
if jq . "$file" > /dev/null 2>&1; then
echo "✓ Geldige JSON: $file"
return 0
else
echo "✗ Ongeldige JSON: $file" >&2
return 1
fi
}Deploy afbreken bij ongeldige configuratie
CONFIG="infra/k8s/app-config.json"
validate_json "$CONFIG" || { echo "Deploy afgebroken: ongeldige configuratie" >&2; exit 1; }Alle JSON-bestanden in een map valideren
find ./config -name "*.json" | while read -r f; do jq . "$f" > /dev/null 2>&1 || echo "ONGELDIG: $f" done
-e / --exit-status gaat verder: het sluit ook af met code 1 wanneer de uitvoer false of null is. Gebruik het om te bevestigen dat een specifiek veld truthy is: jq -e '.feature_flags.new_checkout' config.json.JSON formatteren vanuit bestanden en API-responses
Twee veelvoorkomende JSON-bronnen in shellscripts zijn bestanden op schijf en HTTP API-responses via curl. Elk heeft een iets ander verwerkingspatroon. Voor bestanden is de belangrijkste overweging veilig in-place bewerken. Voor API-responses is het cruciale detail het onderdrukken van de voortgangsbalk van curl zodat deze de invoer van jq niet beschadigt.
Veilige in-place opmaak van een bestand
# Veilig formatteren en overschrijven met een tijdelijk bestand tmp=$(mktemp) jq --indent 2 . config/feature-flags.json > "$tmp" && mv "$tmp" config/feature-flags.json echo "config/feature-flags.json geformatteerd"
Een curl API-response formatteren
# Deploystatus van API formatteren DEPLOY_ID="dep_8f3a2b9c" curl -s \ -H "Authorization: Bearer $DEPLOY_API_TOKEN" \ "https://api.deployments.internal/v1/deploys/$DEPLOY_ID" \ | jq --indent 2 .
Tegelijkertijd formatteren en filteren
# Geformatteerd + filteren op alleen fouten van een monitoring-endpoint
curl -s "https://monitoring.internal/api/events?level=error&limit=10" \
| jq '[.events[] | {id, message, timestamp, service}]' \
|| { echo "Ophalen of parsen van events mislukt" >&2; exit 1; }Het patroon || { ... } is hier cruciaal. Zonder dit patroon wordt een mislukte curl of een misvormde API-response stilzwijgend doorgegeven en werkt de volgende stap in het script op lege of gedeeltelijke gegevens. Als complexe geneste responses moeten worden geïnspecteerd zonder eerst een filterexpressie te schrijven, biedt de browsergebaseerde JSON Formatter de mogelijkheid om de ruwe response te plakken en de boom interactief te verkennen.
JSON formatteren in CI/CD-pipelines
CI is waar JSON-validatiegates het meest van belang zijn — een misvormde configuratie die productie bereikt is veel pijnlijker terug te draaien dan een pipeline-fout. De onderstaande patronen zijn de patronen die ik gebruik in productie SRE-workflows om configuratiefouten te onderscheppen voordat ze ooit een deployment-slot bereiken.
GitHub Actions — alle JSON-configuraties valideren
- name: JSON-configuraties valideren
run: |
echo "JSON-configuratiebestanden valideren..."
find . -name "*.json" -not -path "*/node_modules/*" | while read -r f; do
if ! jq . "$f" > /dev/null 2>&1; then
echo "::error file=$f::Ongeldige JSON-syntaxis"
exit 1
fi
done
echo "Alle JSON-bestanden zijn geldig"Pre-commit hook — gestaagde JSON-bestanden valideren
#!/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 "Ongeldige JSON: $f"; exit 1; }
done
echo "JSON-validatie geslaagd"scripts/validate-json.sh, maak het uitvoerbaar met chmod +x scripts/validate-json.sh, en maak dan een symlink: ln -s ../../scripts/validate-json.sh .git/hooks/pre-commit.JSON-variabelen en Heredocs formatteren in Bash
Shellscripts bouwen JSON-payloads vaak dynamisch op — vanuit omgevingsvariabelen, git-metadata of berekende waarden. Het veiligste patroon is jq -n --arg / --argjson in plaats van stringinterpolatie, die onmiddellijk breekt zodra een waarde een aanhalingsteken of een regelafbreking bevat. Gebruik altijd dubbele aanhalingstekens voor variabelen bij het doorsluizen naar jq om word-splitting op witruimte in de JSON te voorkomen.
Een opgeslagen API-responsevariabele formatteren
# Zet altijd "$API_RESPONSE" tussen aanhalingstekens — witruimte in JSON zou een niet-geciteerde expansie breken echo "$API_RESPONSE" | jq --indent 2 .
Een payload bouwen en formatteren met jq -n
payload=$(jq -n \
--arg env "production" \
--arg version "$(git describe --tags)" \
--argjson replicas 3 \
'{environment: $env, version: $version, replicas: $replicas}')
# De gebouwde payload inspecteren
echo "$payload" | jq .
# Naar een API posten
curl -s -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $DEPLOY_API_TOKEN" \
-d "$payload" \
"https://api.deployments.internal/v1/deploys"--arg bindt altijd een stringwaarde. --argjson parseert de waarde eerst als JSON, zodat getallen, booleans, arrays en objecten kunnen worden doorgegeven zonder ze te citeren in de filterexpressie.JSON formatteren in Bash zonder jq te installeren
Wanneer jq niet beschikbaar is — minimale Docker-images, vergrendelde CI-runners of systemen waar geen pakketten geïnstalleerd kunnen worden — biedt het ingebouwde json.tool-module van Python dezelfde kernfunctionaliteit. Het maakt deel uit van de Python-standaardbibliotheek; als Python 3 is geïnstalleerd, werkt het zonder extra afhankelijkheden.
# Formatteren vanuit een bestand python3 -m json.tool config.json # Inspringbreedte instellen python3 -m json.tool --indent 2 config.json # Sleutels alfabetisch sorteren python3 -m json.tool --sort-keys config.json # Formatteren vanuit stdin (bijv. gepipet van curl) curl -s https://api.deployments.internal/v1/status | python3 -m json.tool
python3 -m json.tool is strenger dan jq: het weigert afsluitende komma's, opmerkingen en JSON5-extensies. Deze strengheid is wenselijk voor validatie van productieconfiguraties, maar kan een knelpunt zijn bij het werken met lakse JSON van externe tools. Het produceert ook geen gekleurde uitvoer, waardoor terminalinspectie minder ergonomisch is dan jq voor interactief gebruik.# Validatie met afsluitcode (zelfde semantiek als jq)
python3 -m json.tool config.json > /dev/null && echo "geldig" || echo "ongeldig"
# Inline string validatie
echo '{"service":"payments-api","healthy":true}' | python3 -m json.tool > /dev/null
echo "Afsluitcode: $?" # 0 = geldigTerminaluitvoer met syntaxismarkering
jq kleurt zijn uitvoer standaard — sleutels in blauw, strings in groen, getallen in wit. Wanneer volledige JSON-syntaxismarkering nodig is in een scrollbare pager, of bij het debuggen van grote geneste responses in een terminalsessie, biedt bat de meest ergonomische ervaring. Beide zijn nuttig voor debuggen en interactieve inspectie; geen van beide mag worden gebruikt bij het schrijven van uitvoer naar bestanden of API-responses.
bat installeren
# macOS brew install bat # Debian / Ubuntu (binary kan batcat heten — maak alias indien nodig) apt-get install -y bat # alias bat=batcat # toevoegen aan ~/.bashrc indien nodig # Verifiëren bat --version # bat 0.24.0
JSON-bestanden bekijken met syntaxismarkering
# Syntaxisgemarkeerde JSON in de pager (druk q om te sluiten) bat config/app-config.json # Paging uitschakelen — direct naar terminal afdrukken bat --paging=never config/app-config.json # jq-uitvoer door bat pipen voor gekleurde inspectie jq '.database' infra/app-config.json | bat --language=json --paging=never
Gekleurde jq-uitvoer in een scrollbare pager
# -C dwingt kleur af, zelfs als stdout geen tty is (bijv. bij pipen naar less) jq -C . logs/deploy-response.json | less -R
bat / jq -C) alleen voor terminalinspectie en debuggen. Verwijder ANSI-kleurcodes voordat u naar logbestanden schrijft of naar andere tools pipet — gebruik jq -M . (--monochrome-output) of bat --plain.Werken met grote JSON-bestanden in Bash
Wanneer een JSON-bestand 50–100 MB overschrijdt, kan het laden in het geheugen met de standaardmodus van jq traag zijn of OOM veroorzaken op geheugenbeperkte hosts (Docker-containers met een limiet van 512 MB, bijvoorbeeld). jq --stream geeft pad/waarde-paren incrementeel uit terwijl het leest, zonder het hele document te bufferen. Voor NDJSON (één JSON-object per regel) heeft jq een efficiëntere native aanpak.
Een groot JSON-bestand streamen met jq --stream
# --stream geeft [pad, scalair] paren uit terwijl jq de invoer leest # Extraheer alle "status"-velden uit een groot logarchief zonder het volledig te laden jq -c --stream 'if length == 2 and (.[0][-1] == "status") then .[1] else empty end' logs/archive-2026-03.json
NDJSON / JSON Lines — één object per regel verwerken
# NDJSON: één JSON-object per regel — gangbaar in Kafka-exports, Fluentd en Logstash
# -R leest ruwe regels; fromjson? slaat regels over die geen geldige JSON zijn
jq -c -R 'fromjson? | {id: .request_id, status: .http_status, latency: .duration_ms}' logs/access-2026-03-13.ndjson > logs/summary.ndjson# Shell-lus alternatief — nuttig wanneer per-regel foutafhandeling nodig is
while IFS= read -r line; do
echo "$line" | jq -c '{id: .request_id, status: .http_status}' 2>/dev/null || echo "OVERGESLAGEN: misvormde regel" >&2
done < logs/access-2026-03-13.ndjsonjq . file.json naar --stream wanneer het bestand groter is dan 50–100 MB of wanneer het proces binnen een container met een geheugenlimiet draait. Voor NDJSON-pipelines heeft jq -R 'fromjson?' de voorkeur boven een shell-while read-lus — het is aanzienlijk sneller omdat het geen subshell per regel hoeft te starten.Veelgemaakte Fouten
Probleem: De shell opent en kapt het uitvoerbestand af voordat jq de invoer leest. Als bron en bestemming hetzelfde pad zijn, leest jq een leeg bestand.
Oplossing: Schrijf eerst naar een mktemp tijdelijk bestand en vervang het origineel dan atomisch met mv.
jq --indent 2 . settings.json > settings.json
tmp=$(mktemp) && jq --indent 2 . settings.json > "$tmp" && mv "$tmp" settings.json
Probleem: Zonder foutafhandeling gaat het script stilzwijgend verder met een leeg of ontbrekend geformatteerd bestand wanneer JSON ongeldig is — downstreamstappen mislukken dan met verwarrende fouten.
Oplossing: Voeg || { echo '...' >&2; exit 1; } toe na elke jq-aanroep die uitvoer produceert die door een latere stap wordt gebruikt.
jq . response.json > formatted.json
jq . response.json > formatted.json || { echo "Ongeldige JSON in response.json" >&2; exit 1; }Probleem: curl drukt standaard een voortgangsbalk af naar stderr. Wanneer stderr wordt samengevoegd met stdout (bijv. in subshells of logopname), verschijnt de voortgangsbalk in de invoer van jq en veroorzaakt een parsefout.
Oplossing: Geef altijd -s (silent) door aan curl bij het doorsluizen naar jq. Gebruik -v of --fail-with-body afzonderlijk als diagnostische uitvoer nodig is.
curl https://api.payments.internal/config | jq .
curl -s https://api.payments.internal/config | jq .
Probleem: De vlag -r / --raw-output verwijdert JSON-aanhalingstekens van top-level stringwaarden — het formatteert geen objecten of arrays. -r . doorgeven aan een objectinvoer produceert hetzelfde compacte object, geen ingesprongen uitvoer.
Oplossing: Gebruik jq . (zonder -r vlag) voor formatteren. Reserveer -r voor het extraheren van platte stringwaarden zoals jq -r '.version' config.json.
jq -r . config.json
jq . config.json
jq vs python3 vs json_pp — Snelle Vergelijking
De keuze tussen tools hangt af van wat beschikbaar is in uw omgeving en wat u nodig heeft naast basisopmaak:
Voor de meeste bash-scripting en CI/CD-werk is jq de juiste standaard — het valideert, formatteert, filtert en biedt betrouwbare afsluitcodes in één enkele binary zonder runtime-afhankelijkheid. Val terug op python3 -m json.tool wanneer geen extra pakketten geïnstalleerd kunnen worden en Python al aanwezig is.
Veelgestelde Vragen
Hoe formateer ik een JSON-bestand in-place met bash?
Leid de uitvoer van jq nooit terug naar hetzelfde bestand — de shell kapt het bestand af voordat jq het leest. Schrijf in plaats daarvan eerst naar een tijdelijk bestand en vervang het origineel vervolgens atomisch met mv.
tmp=$(mktemp) jq --indent 2 . config/app-config.json > "$tmp" && mv "$tmp" config/app-config.json echo "Succesvol in-place geformatteerd"
Hoe valideer ik JSON in een bash-script en stop ik bij een fout?
Pipe of geef het bestand door aan jq en leid stdout om naar /dev/null. Gebruik || om de niet-nul afsluit te onderscheppen en het script af te breken. jq sluit af met code 1 bij elke parsefout, waardoor het betrouwbaar is voor CI-gates.
validate_json() {
local file="$1"
if jq . "$file" > /dev/null 2>&1; then
echo "✓ Geldige JSON: $file"
return 0
else
echo "✗ Ongeldige JSON: $file" >&2
return 1
fi
}
validate_json infra/k8s/app-config.json || exit 1Hoe formatteer ik JSON in bash zonder jq te installeren?
Gebruik het ingebouwde json.tool-module van python3 — het wordt geleverd bij elke standaard Python-installatie en produceert correct ingesprongen uitvoer met dezelfde afsluitcode-semantiek als jq.
# Formatteren vanuit een bestand python3 -m json.tool config.json # Formatteren vanuit stdin (bijv. een curl-respons) curl -s https://api.internal/status | python3 -m json.tool --indent 2
Hoe formatteer ik een curl-respons als JSON in bash?
Geef altijd -s (silent) door aan curl zodat voortgangsbalken de invoer van jq niet beschadigen. Pipe de stdout van curl rechtstreeks naar jq.
DEPLOY_ID="dep_8f3a2b9c" curl -s \ -H "Authorization: Bearer $DEPLOY_API_TOKEN" \ "https://api.deployments.internal/v1/deploys/$DEPLOY_ID" \ | jq --indent 2 .
Hoe formatteer ik alleen een deel van een JSON-bestand met jq?
Gebruik een jq-padexpressie in plaats van het identiteitsfilter (.) om een genest object of array te extraheren en te formatteren. Het resultaat is zelf geformatteerde JSON.
# Alleen het database-configuratieblok formatteren
jq --indent 2 '.database' infra/app-config.json
# Formatteren + events-array filteren op alleen fout-niveau
jq '[.events[] | select(.level == "error") | {id, message, service}]' events.jsonWelke afsluitcode geeft jq terug bij ongeldige JSON?
jq sluit af met code 1 bij elke parsefout en ook wanneer de vlag -e / --exit-status is ingesteld en de uitvoer false of null is. Afsluitcode 0 betekent dat geldige JSON is geparseerd en een waarheidsgetrouwe uitvoer heeft geproduceerd. Afsluitcode 5 betekent dat het systeem een gebruiksfout heeft ondervonden.
# Afsluitcode direct 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 vlag: exit 1 als uitvoer false/null is
echo 'null' | jq -e . > /dev/null 2>&1; echo "exit: $?" # exit: 1Gerelateerde Tools
Browsergebaseerde alternatieven en aanvullingen op bash JSON-opmaak — nuttig wanneer een visuele interface, een deelbare link nodig is, of wanneer buiten een terminal gewerkt wordt:
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.