Formatera JSON i Bash med jq – Komplett Guide
Använd det kostnadsfria JSON Formatter & Beautifier direkt i webbläsaren — ingen installation krävs.
Prova JSON Formatter & Beautifier online →När ett deploy-skript börjar bearbeta API-svar eller validera konfigurationsfiler i CI blir det snabbt avgörande att kunna formatera JSON i bash. De två verktyg som täcker 99 % av verkliga fall är jq och python3 -m json.tool — båda kan hantera JSON-bash-pipelines tillförlitligt, validera med avslutskoder och integreras sömlöst i CI/CD-arbetsflöden. För engångsgranskning utan terminal hanterar den webbläsarbaserade JSON Formatter det omedelbart. Den här guiden täcker jq-installation, pipe- och filformatering, valideringsfunktioner, CI/CD-integration i GitHub Actions, pre-commit hooks, heredoc-mönster och när Python stdlib-fallbacken ska användas.
- •
jq .formaterar OCH validerar samtidigt — avslutar med kod 1 vid ogiltig JSON - • Använd
jq -ei CI-pipelines: nollskilt avslut vid tom/false/null-utdata - •
jq . file.json > /dev/null && echo "valid"— validera utan att ändra utdata - •
python3 -m json.toolfungerar på alla system utan extra installation - • Gör aldrig
jq . f.json > f.json— skalet trunkerar källfilen innan jq läser den
Vad är JSON-formatering i Bash?
JSON-formatering i bash innebär att kompakt, minifierad JSON omvandlas till indragen, lättläst utdata. Underliggande data förändras inte — bara blanksteg och radbrytningar skiljer sig åt. I skriptsammanhang spelar detta roll av två anledningar: läsbarhet vid felsökning och validering när formateraren kontrollerar syntaxen som en bieffekt. Verktyg som jq parsar JSON fullständigt innan de formaterar om det, vilket innebär att ett lyckat formateringskörning även är en implicit giltighetskontroll. Det dubbla beteendet — formatera och validera i ett steg — är det som gör jq så användbart i automatiserade 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 — Formatera JSON i Bash
jq är de facto-standarden för JSON-bearbetning i skalskript (jq 1.6+, bash 4+). Det är en ändamålsbyggd kommandorads-JSON-processor som kan formatera, filtrera, transformera och validera JSON. Identitetsfiltret . skickar inmatningen oförändrad men formaterad. När jq inte kan parsa inmatningen avslutar det med kod 1 — det är vad som gör det idealiskt för skriptning: formatering och validering är en enda operation.
Installera jq
# macOS brew install jq # Debian / Ubuntu apt-get install -y jq # Fedora / RHEL / CentOS dnf install jq # Alpine (Docker-avbildningar) apk add --no-cache jq # Verifiera jq --version # jq-1.7.1
Formatera från stdin och från en fil
# Skicka inline-JSON genom jq via pipe
echo '{"host":"db-prod-01.internal","port":5432}' | jq .
# Formatera en fil direkt (skriver till stdout)
jq . config/feature-flags.json
# Formatera med 4-mellanslags indragning
jq --indent 4 . config/feature-flags.json
# Formatera med tabbar istället för mellanslag
jq --tab . config/feature-flags.jsonSkriva formaterad utdata till en fil
# Spara formaterad utdata (omdirigera INTE tillbaka till samma fil) jq . compact.json > formatted.json # Kompakt (minifiera) — omvänd formatering jq -c . formatted.json
jq avslutar med kod 1 vid ogiltig JSON, kod 0 vid framgång och kod 5 vid användningsfel. Använd detta i if-satser och || exit 1 skydd i hela dina skript.Sortera nycklar och ta bort färg
# Sortera alla nycklar alfabetiskt (användbart för deterministiska diff:ar) jq --sort-keys . config/app-config.json # Inaktivera färgutdata vid skrivning till en loggfil jq --monochrome-output . response.json >> deploy.log
jq Alternativreferens
De vanligaste jq-flaggorna för formaterings- och valideringsarbetsflöden:
Validera JSON i ett Bash-skript
Validering och formatering är samma operation i jq — det parsar innan det skriver ut. Omdirigera stdout till /dev/null när bara avslutskoden behövs utan den formaterade utdatan. Mönstret nedan är återanvändbart i deploy-skript, pre-commit hooks och CI-pipelines. Vid incidenthantering är det första jag gör med ett okänt API-payload att skicka det genom jq — det förvandlar en vägg av minifierad JSON till något jag faktiskt kan läsa och felsöka.
Återanvändbar valideringsfunktion
validate_json() {
local file="$1"
if jq . "$file" > /dev/null 2>&1; then
echo "✓ Giltig JSON: $file"
return 0
else
echo "✗ Ogiltig JSON: $file" >&2
return 1
fi
}Avbryt en deploy vid ogiltig konfiguration
CONFIG="infra/k8s/app-config.json"
validate_json "$CONFIG" || { echo "Avbryter deploy: ogiltig konfiguration" >&2; exit 1; }Validera alla JSON-filer i en katalog
find ./config -name "*.json" | while read -r f; do jq . "$f" > /dev/null 2>&1 || echo "OGILTIG: $f" done
-e / --exit-status går längre: den avslutar också med kod 1 när utdatan är false eller null. Använd den för att kontrollera att ett specifikt fält är sant: jq -e '.feature_flags.new_checkout' config.json.Formatera JSON från filer och API-svar
Två vanliga JSON-källor i skalskript är filer på disk och HTTP API-svar via curl. Vardera har ett lite annorlunda hanteringsmönster. För filer är den viktigaste hänsyn säker redigering på plats. För API-svar är nyckeln att undertrycka curl:s förloppsfält så att det inte korrumperar jq:s inmatning.
Säker formatering på plats av en fil
# Formatera och skriv över säkert med en temporär fil tmp=$(mktemp) jq --indent 2 . config/feature-flags.json > "$tmp" && mv "$tmp" config/feature-flags.json echo "config/feature-flags.json formaterad"
Formatera ett curl API-svar
# Formatera deploystatus från API DEPLOY_ID="dep_8f3a2b9c" curl -s \ -H "Authorization: Bearer $DEPLOY_API_TOKEN" \ "https://api.deployments.internal/v1/deploys/$DEPLOY_ID" \ | jq --indent 2 .
Formatera och filtrera samtidigt
# Hämta formaterat + filtrera till enbart fel från en övervaknings-endpoint
curl -s "https://monitoring.internal/api/events?level=error&limit=10" \
| jq '[.events[] | {id, message, timestamp, service}]' \
|| { echo "Misslyckades att hämta eller parsa händelser" >&2; exit 1; }Mönstret || { ... } är avgörande här. Utan det skickas en misslyckad curl eller ett felaktigt API-svar tyst vidare och nästa steg i skriptet arbetar med tom eller ofullständig data. Om komplexa kapslade svar behöver inspekteras utan att skriva ett filteruttryck först, tillåter den webbläsarbaserade JSON Formatter att klistra in råsvaret och navigera i trädet interaktivt.
Formatera JSON i CI/CD-pipelines
CI är där JSON-valideringsgrindar spelar störst roll — en felformaterad konfiguration som når produktion är mycket mer smärtsam att rulla tillbaka än ett pipeline-misslyckande. Mönstren nedan är de jag använder i produktions-SRE-arbetsflöden för att fånga konfigurationsfel innan de någonsin når ett deployment-slot.
GitHub Actions — validera alla JSON-konfigurationer
- name: Validera JSON-konfigurationer
run: |
echo "Validerar JSON-konfigurationsfiler..."
find . -name "*.json" -not -path "*/node_modules/*" | while read -r f; do
if ! jq . "$f" > /dev/null 2>&1; then
echo "::error file=$f::Ogiltig JSON-syntax"
exit 1
fi
done
echo "Alla JSON-filer är giltiga"Pre-commit hook — validera staged JSON-filer
#!/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 "Ogiltig JSON: $f"; exit 1; }
done
echo "JSON-validering godkänd"scripts/validate-json.sh, gör den körbar med chmod +x scripts/validate-json.sh, och skapa sedan en symbolisk länk: ln -s ../../scripts/validate-json.sh .git/hooks/pre-commit.Formatera JSON-variabler och Heredocs i Bash
Skalskript bygger ofta JSON-payloads dynamiskt — från miljövariabler, git-metadata eller beräknade värden. Det säkraste mönstret är jq -n --arg / --argjson snarare än stränginterpolation, som går sönder i det ögonblick ett värde innehåller ett citattecken eller en radbrytning. Använd alltid dubbla citattecken runt variabler vid pipe till jq för att förhindra orddelning på blanksteg i JSON.
Formatera en lagrad API-svarsvariabel
# Använd alltid "$API_RESPONSE" med citattecken — blanksteg i JSON skulle bryta en ociterad expansion echo "$API_RESPONSE" | jq --indent 2 .
Bygg och formatera ett payload med jq -n
payload=$(jq -n \
--arg env "production" \
--arg version "$(git describe --tags)" \
--argjson replicas 3 \
'{environment: $env, version: $version, replicas: $replicas}')
# Inspektera det byggda payload:et
echo "$payload" | jq .
# Skicka det till ett API
curl -s -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $DEPLOY_API_TOKEN" \
-d "$payload" \
"https://api.deployments.internal/v1/deploys"--arg binder alltid ett strängvärde. --argjson parsar värdet som JSON först, så att tal, booleaner, arrayer och objekt kan skickas utan att citera dem inuti filteruttrycket.Formatera JSON i Bash utan att installera jq
När jq inte är tillgängligt — minimala Docker-avbildningar, låsta CI-runners eller system där paket inte kan installeras — erbjuder Python:s inbyggda json.tool-modul samma kärnfunktionalitet. Det är en del av Python-standardbiblioteket; om Python 3 är installerat fungerar det utan extra beroenden.
# Formatera från en fil python3 -m json.tool config.json # Kontrollera indragningsbredd python3 -m json.tool --indent 2 config.json # Sortera nycklar alfabetiskt python3 -m json.tool --sort-keys config.json # Formatera från stdin (t.ex. via pipe från curl) curl -s https://api.deployments.internal/v1/status | python3 -m json.tool
python3 -m json.tool är striktare än jq: det avvisar avslutande kommatecken, kommentarer och JSON5-tillägg. Denna strikthet är önskvärd för validering av produktionskonfigurationer men kan vara ett friktionspunkt vid arbete med lax JSON från tredjepartsverktyg. Det producerar heller ingen färgad utdata, vilket gör terminalinspektionen mindre ergonomisk än jq för interaktivt bruk.# Validering med avslutskod (samma semantik som jq)
python3 -m json.tool config.json > /dev/null && echo "giltig" || echo "ogiltig"
# Inline-strängvalidering
echo '{"service":"payments-api","healthy":true}' | python3 -m json.tool > /dev/null
echo "Avslutskod: $?" # 0 = giltigTerminalutdata med syntaxmarkering
jq färgar sin utdata som standard — nycklar i blått, strängar i grönt, tal i vitt. När fullständig JSON-syntaxmarkering behövs i en scrollbar pager, eller vid felsökning av stora kapslade svar i en terminalsession, erbjuder bat den mest ergonomiska upplevelsen. Båda är användbara för felsökning och interaktiv inspektion; ingendera bör användas vid skrivning av utdata till filer eller API-svar.
Installera bat
# macOS brew install bat # Debian / Ubuntu (binären kan heta batcat — skapa alias vid behov) apt-get install -y bat # alias bat=batcat # lägg till i ~/.bashrc vid behov # Verifiera bat --version # bat 0.24.0
Visa JSON-filer med syntaxmarkering
# Syntaxmarkerad JSON i pagern (tryck q för att avsluta) bat config/app-config.json # Inaktivera paging — skriv direkt till terminal bat --paging=never config/app-config.json # Skicka jq-utdata genom bat för färgad inspektion jq '.database' infra/app-config.json | bat --language=json --paging=never
Färgad jq-utdata i en scrollbar pager
# -C tvingar färg även när stdout inte är en tty (t.ex. vid pipe till less) jq -C . logs/deploy-response.json | less -R
bat / jq -C) endast för terminalinspektion och felsökning. Ta bort ANSI-färgkoder innan skrivning till loggfiler eller pipe till andra verktyg — använd jq -M . (--monochrome-output) eller bat --plain.Arbeta med stora JSON-filer i Bash
När en JSON-fil överstiger 50–100 MB kan inläsning i minnet med jq:s standardläge vara långsam eller utlösa OOM på minnesbegränsade värdar (Docker-containrar med en 512 MB-gräns, till exempel). jq --stream skickar sökväg/värde-par inkrementellt allt eftersom det läser, utan att buffra hela dokumentet. För NDJSON (ett JSON-objekt per rad) har jq ett effektivare inbyggt tillvägagångssätt.
Streama en stor JSON-fil med jq --stream
# --stream skickar [sökväg, skalär] par allt eftersom jq läser inmatningen # Extrahera alla "status"-fält från ett stort loggarkiv utan att ladda det fullständigt jq -c --stream 'if length == 2 and (.[0][-1] == "status") then .[1] else empty end' logs/archive-2026-03.json
NDJSON / JSON Lines — bearbeta ett objekt per rad
# NDJSON: ett JSON-objekt per rad — vanligt i Kafka-exporter, Fluentd och Logstash
# -R läser råa rader; fromjson? hoppar över rader som inte är giltig JSON
jq -c -R 'fromjson? | {id: .request_id, status: .http_status, latency: .duration_ms}' logs/access-2026-03-13.ndjson > logs/summary.ndjson# Skalloop-alternativ — användbart när felhantering per rad behövs
while IFS= read -r line; do
echo "$line" | jq -c '{id: .request_id, status: .http_status}' 2>/dev/null || echo "HOPPAR ÖVER: felformad rad" >&2
done < logs/access-2026-03-13.ndjsonjq . file.json till --stream när filen är större än 50–100 MB eller när processen körs inuti en container med en minnesgräns. För NDJSON-pipelines föredras jq -R 'fromjson?' framför en skal-while read-loop — det är betydligt snabbare eftersom det undviker att starta ett underskal per rad.Vanliga Misstag
Problem: Skalet öppnar och trunkerar utdatafilen innan jq läser inmatningen. Om källa och mål är samma sökväg läser jq en tom fil.
Lösning: Skriv till en mktemp temporär fil först och ersätt sedan originalet atomiskt med mv.
jq --indent 2 . settings.json > settings.json
tmp=$(mktemp) && jq --indent 2 . settings.json > "$tmp" && mv "$tmp" settings.json
Problem: Utan en felhanterare fortsätter skriptet tyst med en tom eller saknad formaterad fil när JSON är ogiltig — nedströms steg misslyckas sedan med förvirrande fel.
Lösning: Lägg till || { echo '...' >&2; exit 1; } efter varje jq-anrop som producerar utdata som används av ett senare steg.
jq . response.json > formatted.json
jq . response.json > formatted.json || { echo "Ogiltig JSON i response.json" >&2; exit 1; }Problem: curl skriver ut en förloppsfält till stderr som standard. När stderr slås samman med stdout (t.ex. i underskal eller loggfångst) visas förloppsfältstexten i jq:s inmatning och orsakar ett parsningsfel.
Lösning: Skicka alltid -s (tyst) till curl vid pipe till jq. Använd -v eller --fail-with-body separat om diagnostisk utdata behövs.
curl https://api.payments.internal/config | jq .
curl -s https://api.payments.internal/config | jq .
Problem: Flaggan -r / --raw-output tar bort JSON-citattecken från toppnivåsträngvärden — den formaterar inte objekt eller arrayer. Att skicka -r . till ett objektinmatning ger samma kompakta objekt, inte indragen utdata.
Lösning: Använd jq . (utan -r flagga) för formatering. Reservera -r för att extrahera rena strängvärden som jq -r '.version' config.json.
jq -r . config.json
jq . config.json
jq vs python3 vs json_pp — Snabb Jämförelse
Valet mellan verktyg beror på vad som är tillgängligt i din miljö och vad du behöver utöver grundläggande formatering:
För de flesta bash-skriptning och CI/CD-arbete är jq rätt standard — det validerar, formaterar, filtrerar och erbjuder tillförlitliga avslutskoder i en enda binär utan runtime-beroende. Falla tillbaka på python3 -m json.tool när inga extra paket kan installeras och Python redan finns tillgängligt.
Vanliga Frågor
Hur formaterar jag en JSON-fil på plats med bash?
Omdirigera aldrig jq:s utdata tillbaka till samma fil — skalet trunkerar filen innan jq läser den. Skriv istället till en temporär fil först och ersätt sedan originalet atomiskt med mv.
tmp=$(mktemp) jq --indent 2 . config/app-config.json > "$tmp" && mv "$tmp" config/app-config.json echo "Formaterad på plats utan problem"
Hur validerar jag JSON i ett bash-skript och avbryter vid fel?
Skicka filen till jq via pipe eller direkt och omdirigera stdout till /dev/null. Använd || för att fånga det nollskilda avslutet och avbryta skriptet. jq avslutar med kod 1 vid alla parsningsfel, vilket gör det tillförlitligt för CI-grindar.
validate_json() {
local file="$1"
if jq . "$file" > /dev/null 2>&1; then
echo "✓ Giltig JSON: $file"
return 0
else
echo "✗ Ogiltig JSON: $file" >&2
return 1
fi
}
validate_json infra/k8s/app-config.json || exit 1Hur formaterar jag JSON i bash utan att installera jq?
Använd python3:s inbyggda json.tool-modul — det levereras med varje standard Python-installation och producerar korrekt indragen utdata med samma avslutskodssemantik som jq.
# Formatera från en fil python3 -m json.tool config.json # Formatera från stdin (t.ex. ett curl-svar) curl -s https://api.internal/status | python3 -m json.tool --indent 2
Hur formaterar jag ett curl-svar som JSON i bash?
Skicka alltid -s (tyst) till curl så att förloppsindikatorer inte korrumperar jq:s inmatning. Dirigera curl:s stdout direkt till jq.
DEPLOY_ID="dep_8f3a2b9c" curl -s \ -H "Authorization: Bearer $DEPLOY_API_TOKEN" \ "https://api.deployments.internal/v1/deploys/$DEPLOY_ID" \ | jq --indent 2 .
Hur formaterar jag bara en del av en JSON-fil med jq?
Använd ett jq-sökvägsuttryck istället för identitetsfiltret (.) för att extrahera och formatera ett kapslat objekt eller en array. Resultatet är självt formaterad JSON.
# Formatera bara databaskonfigurationsblocket
jq --indent 2 '.database' infra/app-config.json
# Formatera + filtrera events-array till enbart felnivå
jq '[.events[] | select(.level == "error") | {id, message, service}]' events.jsonVilken avslutskod returnerar jq för ogiltig JSON?
jq avslutar med kod 1 för alla parsningsfel och även när flaggan -e / --exit-status är satt och utdata är false eller null. Avslutskod 0 innebär att giltig JSON parsades och producerade sanningsenlig utdata. Avslutskod 5 innebär att systemet stötte på ett användningsfel.
# Testa avslutskod direkt
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 flagga: exit 1 om utdata är false/null
echo 'null' | jq -e . > /dev/null 2>&1; echo "exit: $?" # exit: 1Relaterade Verktyg
Webbläsarbaserade alternativ och komplement till bash JSON-formatering — användbara när ett visuellt gränssnitt, en delbar länk behövs eller när arbete sker utanför en terminal:
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.