Formater JSON en Bash — jq & Exemples
Utilisez le Formateur et Embellisseur JSON gratuit directement dans votre navigateur — sans installation.
Essayer Formateur et Embellisseur JSON en ligne →Quand un script de déploiement commence à traiter des réponses d'API ou à valider des fichiers de configuration en CI, savoir comment formater du JSON en bash devient rapidement indispensable. Les deux outils qui couvrent 99 % des cas concrets sont jq et python3 -m json.tool — tous deux peuvent gérer les pipelines de format json bash de manière fiable, valider avec des codes de sortie et s'intégrer proprement dans les workflows CI/CD. Pour une inspection ponctuelle sans terminal, le Formateur JSON en ligne le gère instantanément. Ce guide couvre l'installation de jq, le formatage via pipe et fichier, les fonctions de validation, l'intégration CI/CD dans GitHub Actions, les hooks pre-commit, les patterns heredoc et quand recourir au fallback de la stdlib Python.
- •
jq .formate ET valide simultanément — quitte avec le code 1 sur JSON invalide - • Utilisez
jq -edans les pipelines CI : sortie non nulle sur output vide/false/null - •
jq . file.json > /dev/null && echo "valid"— valide sans modifier la sortie - •
python3 -m json.toolfonctionne sur n'importe quel système sans installation supplémentaire - • Ne faites jamais
jq . f.json > f.json— le shell tronque le fichier source avant que jq ne le lise
Qu'est-ce que le Formatage JSON en Bash ?
Le formatage JSON en bash consiste à transformer du JSON compact et minifié en une sortie indentée et lisible par les humains. Les données sous-jacentes ne changent pas — seuls les espaces blancs et les sauts de ligne diffèrent. Dans les contextes de scripting, cela importe pour deux raisons : la lisibilité lors du débogage, et la validation quand le formateur vérifie la syntaxe comme effet secondaire. Des outils comme jq analysent le JSON intégralement avant de le reformater, ce qui signifie qu'une exécution de formatage réussie est aussi une vérification implicite de validité. Ce comportement dual — formater et valider en une seule étape — est ce qui rend jq si utile dans les pipelines automatisés.
{"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 — Formater du JSON en Bash
jq est le standard de facto pour le traitement JSON dans les scripts shell (jq 1.6+, bash 4+). C'est un processeur JSON en ligne de commande dédié capable de formater, filtrer, transformer et valider du JSON. Le filtre d'identité . passe l'entrée sans modification, mais formatée. Quand jq ne peut pas analyser l'entrée, il quitte avec le code 1 — c'est ce qui le rend idéal pour le scripting : le formatage et la validation sont une seule opération.
Installer jq
# macOS brew install jq # Debian / Ubuntu apt-get install -y jq # Fedora / RHEL / CentOS dnf install jq # Alpine (images Docker) apk add --no-cache jq # Vérifier jq --version # jq-1.7.1
Formater depuis stdin et depuis un fichier
# Rediriger du JSON inline vers jq
echo '{"host":"db-prod-01.internal","port":5432}' | jq .
# Formater un fichier directement (affiche sur stdout)
jq . config/feature-flags.json
# Formater avec une indentation de 4 espaces
jq --indent 4 . config/feature-flags.json
# Formater en utilisant des tabulations plutôt que des espaces
jq --tab . config/feature-flags.jsonÉcrire la sortie formatée dans un fichier
# Sauvegarder la sortie formatée (ne PAS rediriger vers le même fichier) jq . compact.json > formatted.json # Compact (minifier) — inverse du formatage jq -c . formatted.json
jq quitte avec le code 1 sur JSON invalide, le code 0 en cas de succès, et le code 5 sur les erreurs d'utilisation. Utilisez-le dans les instructions if et les gardes || exit 1 dans vos scripts.Trier les clés et supprimer la couleur
# Trier toutes les clés alphabétiquement (utile pour des diffs déterministes) jq --sort-keys . config/app-config.json # Désactiver la sortie colorée lors de l'écriture dans un fichier de log jq --monochrome-output . response.json >> deploy.log
Référence des Options jq
Les flags jq les plus utilisés pour les workflows de formatage et de validation :
Valider du JSON dans un Script Bash
La validation et le formatage sont la même opération dans jq — il analyse avant d'imprimer. Redirigez stdout vers /dev/null quand vous voulez seulement le code de sortie sans la sortie formatée. Le pattern ci-dessous est réutilisable dans les scripts de déploiement, les hooks pre-commit et les pipelines CI. En réponse aux incidents, la première chose que je fais avec une charge utile d'API inconnue est de la passer dans jq — cela transforme un mur de JSON minifié en quelque chose que je peux réellement lire et déboguer.
Fonction de validation réutilisable
validate_json() {
local file="$1"
if jq . "$file" > /dev/null 2>&1; then
echo "✓ JSON valide : $file"
return 0
else
echo "✗ JSON invalide : $file" >&2
return 1
fi
}Interrompre un déploiement sur configuration invalide
CONFIG="infra/k8s/app-config.json"
validate_json "$CONFIG" || { echo "Déploiement annulé : configuration invalide" >&2; exit 1; }Valider tous les fichiers JSON dans un répertoire
find ./config -name "*.json" | while read -r f; do jq . "$f" > /dev/null 2>&1 || echo "INVALIDE : $f" done
-e / --exit-status va plus loin : il quitte aussi avec le code 1 quand la sortie est false ou null. Utilisez-le pour affirmer qu'un champ spécifique est véridique : jq -e '.feature_flags.new_checkout' config.json.Formater du JSON depuis des Fichiers et des Réponses API
Deux sources courantes de JSON dans les scripts shell sont les fichiers sur disque et les réponses HTTP d'API via curl. Chacune a un pattern de traitement légèrement différent. Pour les fichiers, la principale préoccupation est l'édition sécurisée sur place. Pour les réponses API, le détail clé est de supprimer la barre de progression de curl pour qu'elle ne corrompe pas l'entrée de jq.
Formatage sécurisé sur place d'un fichier
# Formater et écraser en toute sécurité en utilisant un fichier temporaire tmp=$(mktemp) jq --indent 2 . config/feature-flags.json > "$tmp" && mv "$tmp" config/feature-flags.json echo "Formaté config/feature-flags.json"
Formater une réponse API curl
# Formater le statut de déploiement depuis l'API DEPLOY_ID="dep_8f3a2b9c" curl -s \ -H "Authorization: Bearer $DEPLOY_API_TOKEN" \ "https://api.deployments.internal/v1/deploys/$DEPLOY_ID" \ | jq --indent 2 .
Formater et filtrer simultanément
# Obtenir formaté + filtrer uniquement les erreurs depuis un endpoint de monitoring
curl -s "https://monitoring.internal/api/events?level=error&limit=10" \
| jq '[.events[] | {id, message, timestamp, service}]' \
|| { echo "Échec de récupération ou d'analyse des événements" >&2; exit 1; }Le pattern || { ... } est critique ici. Sans lui, un curl échoué ou une réponse API malformée passe silencieusement et l'étape suivante de votre script opère sur des données vides ou partielles. Si vous devez inspecter des réponses imbriquées complexes sans écrire d'abord une expression de filtre, le Formateur JSON en ligne vous permet de coller la réponse brute et de naviguer dans l'arborescence de façon interactive.
Formater du JSON dans les Pipelines CI/CD
Le CI est l'endroit où les portes de validation JSON comptent le plus — une configuration malformée qui atteint la production est bien plus douloureuse à annuler qu'un échec de pipeline. La plupart des concurrents documentent jq pour une utilisation ponctuelle en terminal ; les patterns ci-dessous sont ceux que j'utilise dans des workflows SRE en production pour détecter les erreurs de configuration avant qu'elles n'atteignent un slot de déploiement.
GitHub Actions — valider toutes les configurations JSON
- name: Valider les configurations JSON
run: |
echo "Validation des fichiers de configuration 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::Syntaxe JSON invalide"
exit 1
fi
done
echo "Tous les fichiers JSON sont valides"Hook pre-commit — valider les fichiers JSON en 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 invalide : $f"; exit 1; }
done
echo "Validation JSON réussie"scripts/validate-json.sh, rendez-le exécutable avec chmod +x scripts/validate-json.sh, puis créez un lien symbolique : ln -s ../../scripts/validate-json.sh .git/hooks/pre-commit.Formater des Variables JSON et des Heredocs en Bash
Les scripts shell construisent souvent des charges utiles JSON dynamiquement — à partir de variables d'environnement, de métadonnées git ou de valeurs calculées. Le pattern le plus sûr est jq -n --arg / --argjson plutôt que l'interpolation de chaînes, qui se casse dès qu'une valeur contient une guillemet ou un saut de ligne. Mettez toujours les variables entre guillemets doubles lors de la redirection vers jq pour éviter le découpage de mots sur les espaces blancs du JSON.
Formater une variable de réponse API stockée
# Mettez toujours "$API_RESPONSE" entre guillemets — les espaces dans le JSON casseraient une expansion sans guillemets echo "$API_RESPONSE" | jq --indent 2 .
Construire et formater une charge utile avec jq -n
payload=$(jq -n \
--arg env "production" \
--arg version "$(git describe --tags)" \
--argjson replicas 3 \
'{environment: $env, version: $version, replicas: $replicas}')
# Inspecter la charge utile construite
echo "$payload" | jq .
# La poster vers une 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 lie toujours une valeur de chaîne. --argjson analyse la valeur comme JSON d'abord, vous pouvez donc passer des nombres, des booléens, des tableaux et des objets sans les mettre entre guillemets dans l'expression de filtre.Formater du JSON en Bash sans Installer jq
Quand jq n'est pas disponible — images Docker minimales, runners CI verrouillés ou systèmes où vous ne pouvez pas installer des paquets — le module json.tool intégré de Python fournit la même capacité fondamentale. Il fait partie de la bibliothèque standard Python ; si Python 3 est installé, il fonctionne sans dépendances supplémentaires.
# Formater depuis un fichier python3 -m json.tool config.json # Contrôler la largeur d'indentation python3 -m json.tool --indent 2 config.json # Trier les clés alphabétiquement python3 -m json.tool --sort-keys config.json # Formater depuis stdin (ex. : redirigé depuis curl) curl -s https://api.deployments.internal/v1/status | python3 -m json.tool
python3 -m json.tool est plus strict que jq : il rejette les virgules finales, les commentaires et les extensions JSON5. Cette rigueur est souhaitable pour la validation de configurations en production, mais peut être un point de friction lors du travail avec du JSON laxiste d'outils tiers. Il ne produit pas non plus de sortie colorisée, rendant l'inspection en terminal moins ergonomique que jq pour une utilisation interactive.# Validation avec code de sortie (même sémantique que jq)
python3 -m json.tool config.json > /dev/null && echo "valide" || echo "invalide"
# Validation de chaîne inline
echo '{"service":"payments-api","healthy":true}' | python3 -m json.tool > /dev/null
echo "Code de sortie : $?" # 0 = valideSortie Terminal avec Coloration Syntaxique
jq colorise sa sortie par défaut — les clés en bleu, les chaînes en vert, les nombres en blanc. Quand vous avez besoin d'une coloration syntaxique JSON complète dans un paginateur défilable, ou lors du débogage de grandes réponses imbriquées dans une session terminal, bat offre l'expérience la plus ergonomique. Les deux sont utiles pour le débogage et l'inspection interactive ; aucun ne doit être utilisé lors de l'écriture de sortie vers des fichiers ou des réponses API.
Installer bat
# macOS brew install bat # Debian / Ubuntu (le binaire peut s'appeler batcat — créez un alias si c'est le cas) apt-get install -y bat # alias bat=batcat # ajouter à ~/.bashrc si nécessaire # Vérifier bat --version # bat 0.24.0
Afficher des fichiers JSON avec coloration syntaxique
# JSON avec coloration syntaxique dans le paginateur (appuyez sur q pour quitter) bat config/app-config.json # Désactiver le paginateur — afficher directement dans le terminal bat --paging=never config/app-config.json # Rediriger la sortie de jq vers bat pour une inspection colorée jq '.database' infra/app-config.json | bat --language=json --paging=never
Sortie jq colorée dans un paginateur défilable
# -C force la couleur même quand stdout n'est pas un tty (ex. : lors du pipe vers less) jq -C . logs/deploy-response.json | less -R
bat / jq -C) uniquement pour l'inspection et le débogage en terminal. Supprimez les codes de couleur ANSI avant d'écrire dans des fichiers de log ou de rediriger vers d'autres outils — utilisez jq -M . (--monochrome-output) ou bat --plain.Travailler avec de Grands Fichiers JSON en Bash
Quand un fichier JSON dépasse 50–100 Mo, le charger en mémoire avec le mode par défaut de jq peut être lent ou déclencher un OOM sur des hôtes à mémoire limitée (conteneurs Docker avec une limite de 512 Mo, par exemple). jq --stream émet des paires chemin/valeur de façon incrémentale à la lecture, sans mettre en buffer l'intégralité du document. Pour le NDJSON (un objet JSON par ligne), jq dispose d'une approche native plus efficace.
Traiter en flux un grand fichier JSON avec jq --stream
# --stream émet des paires [chemin, scalaire] au fur et à mesure que jq lit l'entrée # Extraire tous les champs "status" d'une grande archive de logs sans la charger entièrement jq -c --stream 'if length == 2 and (.[0][-1] == "status") then .[1] else empty end' logs/archive-2026-03.json
NDJSON / JSON Lines — traiter un objet par ligne
# NDJSON : un objet JSON par ligne — courant dans les exports Kafka, Fluentd et Logstash
# -R lit les lignes brutes ; fromjson? ignore les lignes qui ne sont pas du JSON valide
jq -c -R 'fromjson? | {id: .request_id, status: .http_status, latency: .duration_ms}' logs/access-2026-03-13.ndjson > logs/summary.ndjson# Alternative avec boucle shell — utile quand vous avez besoin d'une gestion d'erreur par ligne
while IFS= read -r line; do
echo "$line" | jq -c '{id: .request_id, status: .http_status}' 2>/dev/null || echo "IGNORER : ligne malformée" >&2
done < logs/access-2026-03-13.ndjsonjq . file.json standard à --stream quand le fichier dépasse 50–100 Mo ou quand le processus tourne dans un conteneur avec une limite mémoire. Pour les pipelines NDJSON, préférez jq -R 'fromjson?' à une boucle while read shell — c'est nettement plus rapide car cela évite de lancer un sous-shell par ligne.Erreurs Courantes
Problème : Le shell ouvre et tronque le fichier de sortie avant que jq ne lise l'entrée. Si la source et la destination sont le même chemin, jq lit un fichier vide.
Solution : Écrivez d'abord dans un fichier temporaire mktemp, puis remplacez l'original de façon atomique avec mv.
jq --indent 2 . settings.json > settings.json
tmp=$(mktemp) && jq --indent 2 . settings.json > "$tmp" && mv "$tmp" settings.json
Problème : Sans gestionnaire d'erreur, le script continue silencieusement avec un fichier formaté vide ou manquant quand le JSON est invalide — les étapes suivantes échouent alors avec des erreurs confuses.
Solution : Ajoutez || { echo '...' >&2; exit 1; } après chaque appel jq qui produit une sortie utilisée par une étape ultérieure.
jq . response.json > formatted.json
jq . response.json > formatted.json || { echo "JSON invalide dans response.json" >&2; exit 1; }Problème : curl affiche une barre de progression sur stderr par défaut. Quand stderr est fusionné avec stdout (ex. : dans des sous-shells ou la capture de logs), le texte de la barre de progression apparaît dans l'entrée de jq et provoque une erreur d'analyse.
Solution : Passez toujours -s (silencieux) à curl lors du pipe vers jq. Utilisez -v ou --fail-with-body séparément si vous avez besoin d'une sortie de diagnostic.
curl https://api.payments.internal/config | jq .
curl -s https://api.payments.internal/config | jq .
Problème : Le flag -r / --raw-output supprime les guillemets JSON des valeurs de chaîne de niveau supérieur — il ne formate pas les objets ni les tableaux. Passer -r . à un objet produit le même objet compact, pas une sortie indentée.
Solution : Utilisez jq . (sans le flag -r) pour formater. Réservez -r pour extraire des valeurs de chaîne brutes comme jq -r '.version' config.json.
jq -r . config.json
jq . config.json
jq vs python3 vs json_pp — Comparaison Rapide
Le choix entre les outils dépend de ce qui est disponible dans votre environnement et de ce dont vous avez besoin au-delà du formatage basique :
Pour la plupart des travaux de scripting bash et CI/CD, jq est le choix par défaut — il valide, formate, filtre et fournit des codes de sortie fiables dans un seul binaire sans dépendance runtime. Repliez-vous sur python3 -m json.tool quand vous ne pouvez pas installer de paquets supplémentaires et que Python est déjà présent.
Questions Fréquentes
Comment formater un fichier JSON sur place en bash ?
Ne redirigez jamais la sortie de jq vers le même fichier — le shell tronque le fichier avant que jq ne le lise. Écrivez d'abord dans un fichier temporaire, puis remplacez l'original de façon atomique avec mv.
tmp=$(mktemp) jq --indent 2 . config/app-config.json > "$tmp" && mv "$tmp" config/app-config.json echo "Formaté sur place avec succès"
Comment valider du JSON dans un script bash et quitter en cas d'erreur ?
Passez le fichier à jq et redirigez stdout vers /dev/null. Utilisez || pour capturer la sortie non nulle et interrompre le script. jq quitte avec le code 1 pour toute erreur d'analyse, ce qui le rend fiable comme porte de validation en CI.
validate_json() {
local file="$1"
if jq . "$file" > /dev/null 2>&1; then
echo "✓ JSON valide : $file"
return 0
else
echo "✗ JSON invalide : $file" >&2
return 1
fi
}
validate_json infra/k8s/app-config.json || exit 1Comment formater du JSON en bash sans installer jq ?
Utilisez le module json.tool intégré de python3 — il est fourni avec toute installation standard de Python et produit une sortie correctement indentée avec la même sémantique de code de sortie que jq.
# Formater depuis un fichier python3 -m json.tool config.json # Formater depuis stdin (ex. : une réponse curl) curl -s https://api.internal/status | python3 -m json.tool --indent 2
Comment formater du JSON à partir d'une réponse curl en bash ?
Passez toujours -s (silencieux) à curl pour que les barres de progression ne corrompent pas l'entrée de jq. Redirigez le stdout de curl directement dans jq.
DEPLOY_ID="dep_8f3a2b9c" curl -s \ -H "Authorization: Bearer $DEPLOY_API_TOKEN" \ "https://api.deployments.internal/v1/deploys/$DEPLOY_ID" \ | jq --indent 2 .
Comment formater seulement une partie d'un fichier JSON avec jq ?
Utilisez une expression de chemin jq plutôt que le filtre d'identité (.) pour extraire et formater un objet ou un tableau imbriqué. Le résultat est lui-même du JSON formaté.
# Formater uniquement le bloc de configuration de la base de données
jq --indent 2 '.database' infra/app-config.json
# Formater + filtrer le tableau d'événements au niveau erreur uniquement
jq '[.events[] | select(.level == "error") | {id, message, service}]' events.jsonQuel code de sortie jq retourne-t-il pour du JSON invalide ?
jq quitte avec le code 1 pour toute erreur d'analyse, et aussi lorsque le flag -e / --exit-status est actif et que la sortie est false ou null. Le code de sortie 0 signifie que du JSON valide a été analysé avec une sortie véridique. Le code de sortie 5 signifie une erreur d'utilisation.
# Tester le code de sortie directement
echo '{"ok":true}' | jq . > /dev/null 2>&1; echo "sortie : $?" # sortie : 0
echo '{mauvais json}' | jq . > /dev/null 2>&1; echo "sortie : $?" # sortie : 1
# flag -e : quitte 1 si la sortie est false/null
echo 'null' | jq -e . > /dev/null 2>&1; echo "sortie : $?" # sortie : 1Outils Connexes
Alternatives et compléments en ligne pour le formatage JSON en bash — utiles quand vous avez besoin d'une interface visuelle, d'un lien partageable ou que vous travaillez en dehors d'un 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.