Formattare JSON in Bash — jq & Esempi
Usa il Formattatore e Abbellitore JSON gratuito direttamente nel tuo browser — nessuna installazione.
Prova Formattatore e Abbellitore JSON online →Quando uno script di deployment inizia a elaborare risposte API o a validare file di configurazione in CI, sapere come formattare JSON in bash diventa rapidamente essenziale. I due strumenti che coprono il 99% dei casi reali sono jq e python3 -m json.tool — entrambi possono gestire pipeline di format json bash in modo affidabile, validare con codici di uscita e integrarsi in modo pulito nei workflow CI/CD. Per ispezioni occasionali senza terminale, il Formattatore JSON basato su browser lo gestisce istantaneamente. Questa guida copre l'installazione di jq, la formattazione da pipe e file, le funzioni di validazione, l'integrazione CI/CD in GitHub Actions, i hook pre-commit, i pattern heredoc e quando ricorrere al fallback della stdlib Python.
- •
jq .formatta E valida simultaneamente — esce con codice 1 su JSON non valido - • Usa
jq -enelle pipeline CI: uscita non-zero su output vuoto/false/null - •
jq . file.json > /dev/null && echo "valid"— valida senza modificare l'output - •
python3 -m json.toolfunziona su qualsiasi sistema senza installazione aggiuntiva - • Non fare mai
jq . f.json > f.json— la shell tronca il file sorgente prima che jq lo legga
Cos'è la Formattazione JSON in Bash?
La formattazione JSON in bash significa trasformare JSON compatto e minificato in output indentato e leggibile dagli esseri umani. I dati sottostanti non cambiano — differiscono solo gli spazi bianchi e le interruzioni di riga. Nei contesti di scripting questo è importante per due ragioni: leggibilità durante il debug, e validazione quando il formattatore verifica la sintassi come effetto collaterale. Strumenti come jq analizzano il JSON completamente prima di riformattarlo, il che significa che un'esecuzione di formattazione riuscita è anche una verifica implicita di validità. Questo comportamento duale — formattare e validare in un unico passaggio — è ciò che rende jq così utile nelle pipeline automatizzate.
{"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 — Formattare JSON in Bash
jq è lo standard de facto per l'elaborazione JSON negli script shell (jq 1.6+, bash 4+). È un processore JSON da riga di comando appositamente costruito che può formattare, filtrare, trasformare e validare JSON. Il filtro identità . trasmette l'input invariato, ma formattato. Quando jq non riesce ad analizzare l'input esce con codice 1 — questo è ciò che lo rende ideale per lo scripting: formattazione e validazione sono un'unica operazione.
Installare jq
# macOS brew install jq # Debian / Ubuntu apt-get install -y jq # Fedora / RHEL / CentOS dnf install jq # Alpine (immagini Docker) apk add --no-cache jq # Verificare jq --version # jq-1.7.1
Formattare da stdin e da un file
# Inviare JSON inline attraverso jq
echo '{"host":"db-prod-01.internal","port":5432}' | jq .
# Formattare un file direttamente (stampa su stdout)
jq . config/feature-flags.json
# Formattare con indentazione di 4 spazi
jq --indent 4 . config/feature-flags.json
# Formattare usando tabulazioni anziché spazi
jq --tab . config/feature-flags.jsonScrivere l'output formattato su un file
# Salvare l'output formattato (NON reindirizzare allo stesso file) jq . compact.json > formatted.json # Compatto (minificare) — inverso della formattazione jq -c . formatted.json
jq esce con codice 1 su JSON non valido, codice 0 in caso di successo, e codice 5 per errori di utilizzo. Usalo in istruzioni if e guardie || exit 1 in tutti i tuoi script.Ordinare le chiavi e rimuovere i colori
# Ordinare tutte le chiavi alfabeticamente (utile per diff deterministici) jq --sort-keys . config/app-config.json # Disabilitare l'output a colori quando si scrive su un file di log jq --monochrome-output . response.json >> deploy.log
Riferimento delle Opzioni jq
I flag jq più comunemente usati per i workflow di formattazione e validazione:
Validare JSON in uno Script Bash
Validazione e formattazione sono la stessa operazione in jq — analizza prima di stampare. Reindirizza stdout verso /dev/null quando vuoi solo il codice di uscita senza l'output formattato. Il pattern seguente è riutilizzabile in script di deployment, hook pre-commit e pipeline CI. In risposta agli incidenti, la prima cosa che faccio con un payload API sconosciuto è inviarlo attraverso jq — trasforma una parete di JSON minificato in qualcosa che posso effettivamente leggere e fare debug.
Funzione di validazione riutilizzabile
validate_json() {
local file="$1"
if jq . "$file" > /dev/null 2>&1; then
echo "✓ JSON valido: $file"
return 0
else
echo "✗ JSON non valido: $file" >&2
return 1
fi
}Interrompere un deployment su configurazione non valida
CONFIG="infra/k8s/app-config.json"
validate_json "$CONFIG" || { echo "Deployment annullato: configurazione non valida" >&2; exit 1; }Validare tutti i file JSON in una directory
find ./config -name "*.json" | while read -r f; do jq . "$f" > /dev/null 2>&1 || echo "NON VALIDO: $f" done
-e / --exit-status va oltre: esce anche con codice 1 quando l'output è false o null. Usalo per affermare che un campo specifico è veritiero: jq -e '.feature_flags.new_checkout' config.json.Formattare JSON da File e Risposte API
Due fonti comuni di JSON negli script shell sono i file su disco e le risposte HTTP API via curl. Ciascuna ha un pattern di gestione leggermente diverso. Per i file, la preoccupazione principale è la modifica sicura in loco. Per le risposte API, il dettaglio chiave è sopprimere la barra di avanzamento di curl per non corrompere l'input di jq.
Formattazione sicura in loco di un file
# Formattare e sovrascrivere in modo sicuro usando un file temporaneo tmp=$(mktemp) jq --indent 2 . config/feature-flags.json > "$tmp" && mv "$tmp" config/feature-flags.json echo "Formattato config/feature-flags.json"
Formattare una risposta API curl
# Formattare lo stato di deployment dall'API DEPLOY_ID="dep_8f3a2b9c" curl -s \ -H "Authorization: Bearer $DEPLOY_API_TOKEN" \ "https://api.deployments.internal/v1/deploys/$DEPLOY_ID" \ | jq --indent 2 .
Formattare e filtrare simultaneamente
# Ottenere formattato + filtrare solo gli errori da un endpoint di monitoraggio
curl -s "https://monitoring.internal/api/events?level=error&limit=10" \
| jq '[.events[] | {id, message, timestamp, service}]' \
|| { echo "Impossibile recuperare o analizzare gli eventi" >&2; exit 1; }Il pattern || { ... } è fondamentale qui. Senza di esso, un curl fallito o una risposta API malformata passa silenziosamente e il passo successivo dello script opera su dati vuoti o parziali. Se hai bisogno di ispezionare risposte annidate complesse senza scrivere prima un'espressione di filtro, il Formattatore JSON basato su browser ti permette di incollare la risposta grezza e navigare l'albero in modo interattivo.
Formattare JSON nelle Pipeline CI/CD
CI è dove i gate di validazione JSON contano di più — una configurazione malformata che raggiunge la produzione è molto più dolorosa da ripristinare di un fallimento della pipeline. La maggior parte dei concorrenti documenta jq per uso terminale occasionale; i pattern seguenti sono quelli che uso nei workflow SRE in produzione per rilevare gli errori di configurazione prima che raggiungano uno slot di deployment.
GitHub Actions — validare tutte le configurazioni JSON
- name: Valida configurazioni JSON
run: |
echo "Validazione dei file di configurazione JSON..."
find . -name "*.json" -not -path "*/node_modules/*" | while read -r f; do
if ! jq . "$f" > /dev/null 2>&1; then
echo "::error file=$f::Sintassi JSON non valida"
exit 1
fi
done
echo "Tutti i file JSON sono validi"Hook pre-commit — validare i file JSON in staging
#!/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 "JSON non valido: $f"; exit 1; }
done
echo "Validazione JSON superata"scripts/validate-json.sh, rendilo eseguibile con chmod +x scripts/validate-json.sh, poi crea un symlink: ln -s ../../scripts/validate-json.sh .git/hooks/pre-commit.Formattare Variabili JSON e Heredoc in Bash
Gli script shell spesso costruiscono payload JSON dinamicamente — da variabili d'ambiente, metadati git o valori calcolati. Il pattern più sicuro è jq -n --arg / --argjson piuttosto che l'interpolazione di stringhe, che si rompe nel momento in cui un valore contiene una virgoletta o un'interruzione di riga. Metti sempre tra virgolette doppie le variabili quando le si invia a jq per evitare la divisione di parole sugli spazi bianchi nel JSON.
Formattare una variabile con risposta API memorizzata
# Metti sempre "$API_RESPONSE" tra virgolette — gli spazi nel JSON romperebbero un'espansione senza virgolette echo "$API_RESPONSE" | jq --indent 2 .
Costruire e formattare un payload con jq -n
payload=$(jq -n \
--arg env "production" \
--arg version "$(git describe --tags)" \
--argjson replicas 3 \
'{environment: $env, version: $version, replicas: $replicas}')
# Ispezionare il payload costruito
echo "$payload" | jq .
# Inviarlo a un'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 associa sempre un valore stringa. --argjson analizza il valore come JSON prima, quindi puoi passare numeri, booleani, array e oggetti senza metterli tra virgolette nell'espressione del filtro.Formattare JSON in Bash senza Installare jq
Quando jq non è disponibile — immagini Docker minimali, runner CI con restrizioni o sistemi dove non puoi installare pacchetti — il modulo json.tool integrato di Python offre la stessa capacità di base. Fa parte della libreria standard Python; se Python 3 è installato, funziona senza dipendenze aggiuntive.
# Formattare da un file python3 -m json.tool config.json # Controllare la larghezza dell'indentazione python3 -m json.tool --indent 2 config.json # Ordinare le chiavi alfabeticamente python3 -m json.tool --sort-keys config.json # Formattare da stdin (es. inviato da curl) curl -s https://api.deployments.internal/v1/status | python3 -m json.tool
python3 -m json.tool è più rigoroso di jq: rifiuta virgole finali, commenti ed estensioni JSON5. Questa rigidità è desiderabile per la validazione di configurazioni in produzione, ma può essere un punto di attrito quando si lavora con JSON lassista di strumenti di terze parti. Non produce nemmeno output colorato, rendendo l'ispezione nel terminale meno ergonomica di jq per l'uso interattivo.# Validazione con codice di uscita (stessa semantica di jq)
python3 -m json.tool config.json > /dev/null && echo "valido" || echo "non valido"
# Validazione di stringa inline
echo '{"service":"payments-api","healthy":true}' | python3 -m json.tool > /dev/null
echo "Codice di uscita: $?" # 0 = validoOutput Terminale con Evidenziazione della Sintassi
jq colorizza il suo output per impostazione predefinita — chiavi in blu, stringhe in verde, numeri in bianco. Quando hai bisogno di evidenziazione completa della sintassi JSON in un pager scorrevole, o durante il debug di grandi risposte annidate in una sessione terminale, bat offre l'esperienza più ergonomica. Entrambi sono utili per il debug e l'ispezione interattiva; nessuno dovrebbe essere usato quando si scrive output su file o risposte API.
Installare bat
# macOS brew install bat # Debian / Ubuntu (il binario potrebbe chiamarsi batcat — crea un alias se necessario) apt-get install -y bat # alias bat=batcat # aggiungere a ~/.bashrc se necessario # Verificare bat --version # bat 0.24.0
Visualizzare file JSON con evidenziazione della sintassi
# JSON con evidenziazione della sintassi nel pager (premi q per uscire) bat config/app-config.json # Disabilitare il paging — stampare direttamente nel terminale bat --paging=never config/app-config.json # Inviare l'output di jq attraverso bat per ispezione colorata jq '.database' infra/app-config.json | bat --language=json --paging=never
Output jq colorato in un pager scorrevole
# -C forza il colore anche quando stdout non è un tty (es. quando si invia a less) jq -C . logs/deploy-response.json | less -R
bat / jq -C) solo per ispezione e debug nel terminale. Rimuovi i codici colore ANSI prima di scrivere su file di log o inviare ad altri strumenti — usa jq -M . (--monochrome-output) o bat --plain.Lavorare con File JSON di Grandi Dimensioni in Bash
Quando un file JSON supera i 50–100 MB, caricarlo in memoria con la modalità predefinita di jq può essere lento o innescare OOM su host con memoria limitata (container Docker con un limite di 512 MB, ad esempio). jq --stream emette coppie percorso/valore in modo incrementale durante la lettura, senza buffering dell'intero documento. Per NDJSON (un oggetto JSON per riga), jq ha un approccio nativo più efficiente.
Elaborare in streaming un grande file JSON con jq --stream
# --stream emette coppie [percorso, scalare] mentre jq legge l'input # Estrarre tutti i campi "status" da un grande archivio di log senza caricarlo completamente jq -c --stream 'if length == 2 and (.[0][-1] == "status") then .[1] else empty end' logs/archive-2026-03.json
NDJSON / JSON Lines — elaborare un oggetto per riga
# NDJSON: un oggetto JSON per riga — comune nelle esportazioni Kafka, Fluentd e Logstash
# -R legge righe grezze; fromjson? salta le righe che non sono JSON valido
jq -c -R 'fromjson? | {id: .request_id, status: .http_status, latency: .duration_ms}' logs/access-2026-03-13.ndjson > logs/summary.ndjson# Alternativa con ciclo shell — utile quando si ha bisogno di gestione errori per riga
while IFS= read -r line; do
echo "$line" | jq -c '{id: .request_id, status: .http_status}' 2>/dev/null || echo "SALTA: riga malformata" >&2
done < logs/access-2026-03-13.ndjsonjq . file.json standard a --stream quando il file è più grande di 50–100 MB o quando il processo gira all'interno di un container con limite di memoria. Per le pipeline NDJSON, preferisci jq -R 'fromjson?' rispetto a un ciclo while read shell — è significativamente più veloce perché evita di creare un subshell per riga.Errori Comuni
Problema: La shell apre e tronca il file di output prima che jq legga l'input. Se sorgente e destinazione sono lo stesso percorso, jq legge un file vuoto.
Soluzione: Scrivi prima in un file temporaneo mktemp, poi sostituisci l'originale in modo atomico con mv.
jq --indent 2 . settings.json > settings.json
tmp=$(mktemp) && jq --indent 2 . settings.json > "$tmp" && mv "$tmp" settings.json
Problema: Senza un gestore di errori, lo script continua silenziosamente con un file formattato vuoto o mancante quando il JSON non è valido — i passaggi successivi falliscono poi con errori confusi.
Soluzione: Aggiungi || { echo '...' >&2; exit 1; } dopo ogni chiamata jq che produce output usato da un passaggio successivo.
jq . response.json > formatted.json
jq . response.json > formatted.json || { echo "JSON non valido in response.json" >&2; exit 1; }Problema: curl stampa una barra di avanzamento su stderr per impostazione predefinita. Quando stderr viene unito a stdout (es. nei subshell o nella cattura dei log), il testo della barra di avanzamento appare nell'input di jq e causa un errore di analisi.
Soluzione: Passa sempre -s (silenzioso) a curl quando si invia a jq. Usa -v o --fail-with-body separatamente se hai bisogno di output diagnostico.
curl https://api.payments.internal/config | jq .
curl -s https://api.payments.internal/config | jq .
Problema: Il flag -r / --raw-output rimuove le virgolette JSON dai valori stringa di primo livello — non formatta oggetti o array. Passare -r . a un oggetto produce lo stesso oggetto compatto, non output indentato.
Soluzione: Usa jq . (senza il flag -r) per formattare. Riserva -r per estrarre valori stringa puri come jq -r '.version' config.json.
jq -r . config.json
jq . config.json
jq vs python3 vs json_pp — Confronto Rapido
La scelta tra strumenti dipende da ciò che è disponibile nel tuo ambiente e da ciò di cui hai bisogno oltre alla formattazione di base:
Per la maggior parte del lavoro di scripting bash e CI/CD, jq è il default corretto — valida, formatta, filtra e fornisce codici di uscita affidabili in un singolo binario senza dipendenza runtime. Ricorri a python3 -m json.tool quando non puoi installare pacchetti aggiuntivi e Python è già presente.
Domande Frequenti
Come si formatta un file JSON in loco usando bash?
Non reindirizzare mai l'output di jq allo stesso file — la shell tronca il file prima che jq lo legga. Scrivi prima in un file temporaneo, poi sostituisci l'originale in modo atomico con mv.
tmp=$(mktemp) jq --indent 2 . config/app-config.json > "$tmp" && mv "$tmp" config/app-config.json echo "Formattato in loco con successo"
Come si valida JSON in uno script bash e si esce in caso di errore?
Passa il file a jq e reindirizza stdout verso /dev/null. Usa || per catturare l'uscita non-zero e interrompere lo script. jq esce con codice 1 per qualsiasi errore di analisi, rendendolo affidabile come gate di validazione in CI.
validate_json() {
local file="$1"
if jq . "$file" > /dev/null 2>&1; then
echo "✓ JSON valido: $file"
return 0
else
echo "✗ JSON non valido: $file" >&2
return 1
fi
}
validate_json infra/k8s/app-config.json || exit 1Come si formatta JSON in bash senza installare jq?
Usa il modulo json.tool integrato di python3 — è incluso in ogni installazione standard di Python e produce output correttamente indentato con la stessa semantica di codice di uscita di jq.
# Formattare da un file python3 -m json.tool config.json # Formattare da stdin (es. una risposta curl) curl -s https://api.internal/status | python3 -m json.tool --indent 2
Come si formatta JSON da una risposta curl in bash?
Passa sempre -s (silenzioso) a curl in modo che le barre di avanzamento non corrompano l'input di jq. Reindirizza lo stdout di curl direttamente in jq.
DEPLOY_ID="dep_8f3a2b9c" curl -s \ -H "Authorization: Bearer $DEPLOY_API_TOKEN" \ "https://api.deployments.internal/v1/deploys/$DEPLOY_ID" \ | jq --indent 2 .
Come si formatta solo una parte di un file JSON con jq?
Usa un'espressione di percorso jq invece del filtro identità (.) per estrarre e formattare un oggetto o array annidato. Il risultato è a sua volta JSON formattato.
# Formattare solo il blocco di configurazione del database
jq --indent 2 '.database' infra/app-config.json
# Formattare + filtrare l'array degli eventi solo al livello di errore
jq '[.events[] | select(.level == "error") | {id, message, service}]' events.jsonQuale codice di uscita restituisce jq per JSON non valido?
jq esce con codice 1 per qualsiasi errore di analisi e anche quando il flag -e / --exit-status è attivo e l'output è false o null. Il codice di uscita 0 significa che è stato analizzato JSON valido con output veritiero. Il codice di uscita 5 indica un errore di utilizzo.
# Testare il codice di uscita direttamente
echo '{"ok":true}' | jq . > /dev/null 2>&1; echo "uscita: $?" # uscita: 0
echo '{json errato}' | jq . > /dev/null 2>&1; echo "uscita: $?" # uscita: 1
# flag -e: esce 1 se l'output è false/null
echo 'null' | jq -e . > /dev/null 2>&1; echo "uscita: $?" # uscita: 1Strumenti Correlati
Alternative e complementi basati su browser per la formattazione JSON in bash — utili quando hai bisogno di un'interfaccia visuale, un link condivisibile o stai lavorando fuori da un terminale:
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.