Formattare JSON in Bash — jq & Esempi

·SRE & Shell Scripting Specialist·Revisionato daErik Lindqvist·Pubblicato

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.

PUNTI CHIAVE
  • jq . formatta E valida simultaneamente — esce con codice 1 su JSON non valido
  • • Usa jq -e nelle 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.tool funziona 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.

Before · json
After · json
{"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

Bash
# 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

Bash
# 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.json

Scrivere l'output formattato su un file

Bash
# Salvare l'output formattato (NON reindirizzare allo stesso file)
jq . compact.json > formatted.json

# Compatto (minificare) — inverso della formattazione
jq -c . formatted.json
Nota: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

Bash
# 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:

Opzione
Tipo
Predefinito
Descrizione
.
filtro
Filtro identità — formatta e visualizza l'input completo senza modifiche.
--indent N
int
2
Imposta l'indentazione a N spazi (0–7). Usa 2 o 4 per la formattazione standard.
--tab
flag
off
Indenta con un carattere di tabulazione anziché spazi.
-c / --compact-output
flag
off
Comprime l'output in una singola riga (minifica). Annulla il pretty-print.
-r / --raw-output
flag
off
Stampa le stringhe senza virgolette JSON. Utile per estrarre valori di testo normale.
-e / --exit-status
flag
off
Esce con codice 1 se l'output è false o null. Ideale per le asserzioni CI.
-M / --monochrome-output
flag
off
Disabilita l'output a colori — utile quando si reindirizza su file o destinazioni non terminali.
-S / --sort-keys
flag
off
Ordina tutte le chiavi degli oggetti alfabeticamente a ogni livello di annidamento.
-n / --null-input
flag
off
Non legge input; usare con --arg / --argjson per costruire JSON from scratch.
--arg name val
string
Associa una stringa shell come variabile jq nominata ($name) accessibile nel filtro.

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

Bash
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

Bash
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

Bash
find ./config -name "*.json" | while read -r f; do
  jq . "$f" > /dev/null 2>&1 || echo "NON VALIDO: $f"
done
Nota:Il flag -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

Bash
# 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

Bash
# 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

Bash
# 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

YAML
- 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

Bash
#!/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"
Nota:Salva l'hook pre-commit in 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

Bash
# 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

Bash
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"
Nota:--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.

Bash
# 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
Attenzione: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.
Bash
# 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 = valido

Output 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

Bash
# 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

Bash
# 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

Bash
# -C forza il colore anche quando stdout non è un tty (es. quando si invia a less)
jq -C . logs/deploy-response.json | less -R
Attenzione:Usa l'output colorato (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

Bash
# --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

Bash
# 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
Bash
# 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.ndjson
Nota:Passa dal jq . 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

Sovrascrivere il file sorgente con la redirezione shell

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.

Before · Bash
After · Bash
jq --indent 2 . settings.json > settings.json
tmp=$(mktemp) && jq --indent 2 . settings.json > "$tmp" && mv "$tmp" settings.json
Non gestire i fallimenti di jq negli script

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.

Before · Bash
After · Bash
jq . response.json > formatted.json
jq . response.json > formatted.json || { echo "JSON non valido in response.json" >&2; exit 1; }
Dimenticare -s con curl

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.

Before · Bash
After · Bash
curl https://api.payments.internal/config | jq .
curl -s https://api.payments.internal/config | jq .
Usare jq -r . aspettandosi JSON formattato

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.

Before · Bash
After · Bash
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:

Tool
Valida
Colorizza
Compatibile CI
Codici di uscita
Controllo indentazione
Install
jq
✅ (codice 1)
✅ --indent N
brew / apt / dnf
python3 -m json.tool
✅ (rigoroso)
✅ (codice 1)
✅ --indent N
Incluso (Python)
json_pp (Perl)
⚠️ parziale
⚠️ variabile
Incluso (Perl)
fx (Node.js)
⚠️ parziale
⚠️ limitato
npm install -g fx
node -e JSON.parse
✅ JSON.stringify
Incluso (Node.js)

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.

Bash
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.

Bash
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 1

Come 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.

Bash
# 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.

Bash
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.

Bash
# 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.json

Quale 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.

Bash
# 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: 1

Strumenti 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:

Disponibile anche in:PythonGoJavaScript
NO
Nadia OkonkwoSRE & Shell Scripting Specialist

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.

EL
Erik LindqvistRevisore tecnico

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.