← Tous les articles

Tutoriel jq : filtrer et transformer du JSON

Un tutoriel jq pratique : installation, pretty-print et minify, sélection de champs, filtrage de tableaux avec select, transformations avec map, plus des recettes prêtes à copier-coller.

jq est l'outil standard en ligne de commande pour découper, filtrer et transformer du JSON. Il transforme des one-liners en un puissant langage de requête pour les réponses d'API, les fichiers de log et la configuration. Ce tutoriel couvre l'installation, les filtres centraux que tu utiliseras au quotidien, et un ensemble de recettes prêtes à copier-coller pour les tâches les plus fréquentes.

Qu'est-ce que jq ?

jq lit du JSON depuis un fichier ou l'entrée standard, applique un filter, puis écrit du JSON (ou du texte brut) sur la sortie standard. Il pretty-printe par défaut et n'envoie tes données nulle part —— c'est un binaire local, idéal pour des payloads sensibles.

Installer jq

# macOS
brew install jq

# Debian / Ubuntu
sudo apt-get install jq

# Windows (winget ou choco)
winget install jqlang.jq

# Vérification
jq --version

Le filtre identity : pretty-print de tout

Le filtre le plus simple, ., renvoie l'entrée inchangée —— ce qui fait de jq un formateur instantané :

# Pretty-print un fichier
jq . data.json

# Pretty-print une réponse curl
curl -s https://api.example.com/users | jq .

# À l'inverse : minify (sortie compacte)
jq -c . data.json

Sélectionner des champs

Plonge dans les objets avec .key, et dans les tableaux avec [] :

echo '{"user":{"name":"Ada","age":36}}' | jq '.user.name'
# "Ada"

# Tous les éléments d'un tableau
echo '[{"id":1},{"id":2}]' | jq '.[]'
# {"id":1}
# {"id":2}

# Un champ pour chaque élément du tableau
echo '[{"id":1,"name":"Ada"},{"id":2,"name":"Bob"}]' | jq '.[].name'
# "Ada"
# "Bob"

# Enlève les guillemets JSON avec -r (raw output)
jq -r '.[].name' users.json

Filtrer avec select

# Garder uniquement les objets correspondant à une condition
echo '[{"name":"Ada","active":true},{"name":"Bob","active":false}]' \
  | jq '.[] | select(.active == true)'
# {"name":"Ada","active":true}

# Comparaison numérique
jq '.[] | select(.age > 30)' users.json

Transformer avec map et construction d'objets

# Reformule chaque élément en un nouvel objet
echo '[{"id":1,"name":"Ada","email":"a@x.com"}]' \
  | jq 'map({ userId: .id, label: .name })'
# [{"userId":1,"label":"Ada"}]

# Extrais une liste plate de valeurs
jq '[.[].email]' users.json     # ["a@x.com", ...]

# Enchaîne des filtres avec |
jq '.items | map(.price) | add' order.json   # somme de tous les prix

Recettes courantes

TâcheCommande
Pretty-printjq . file.json
Minifyjq -c . file.json
Obtenir un champjq '.data.token' resp.json
Chaîne brute (sans guillemets)jq -r '.token' resp.json
Compter les éléments d'un tableaujq '. | length' list.json
Keys d'un objetjq 'keys' obj.json
Filtrer des lignesjq '.[] | select(.active)'
Trier par un champjq 'sort_by(.age)'
Sommer un champjq '[.[].amount] | add'
Trier les keys d'un objetjq --sort-keys . file.json
Valider (via exit code)jq empty file.json

Remodeler des objets : to_entries / from_entries

Les deux transformateurs de forme d'objet les plus utiles de jq :

# Renomme chaque key (ici en minuscules)
echo '{"Name":"Ada","Active":true}' \
  | jq 'with_entries(.key |= ascii_downcase)'
# → {"name":"Ada","active":true}

# Élimine les keys dont la valeur est null
jq 'with_entries(select(.value != null))' file.json

# Objet ⇄ tableau de paires
jq 'to_entries' file.json     # → [{"key":"name","value":"Ada"}, ...]
jq 'from_entries' pairs.json  # → {"name":"Ada", ...}

Interpolation et formats de sortie : \(.x), @csv, @json, @base64

jq a de l'interpolation de strings et des format strings intégrées pour transformer du JSON en d'autres formats :

# Interpolation de string dans une string entre guillemets
jq -r '"\(.user) bought \(.items|length) items"' order.json

# Une ligne CSV par objet
jq -r '.[] | [.id, .name, .total] | @csv' orders.json

# JSON inline pour les shells (litéral de chaîne échappé)
jq -r '.user | @json' record.json

# Encode une valeur en Base64 (pratique pour les tokens / data URIs)
jq -r '.payload | @base64' message.json
# Côté décodage : jq accepte @base64d dans les versions plus récentes

Valider du JSON avec jq

Comme jq sort avec un code non nul sur une entrée invalide, jq empty file.json est un check de validité propre pour scripts et CI —— voir Comment valider du JSON pour d'autres approches de validation.

Quand un outil navigateur est plus rapide

jq brille dans les scripts et pipelines, mais pour un coup ponctuel —— formater une réponse collée, inspecter une structure inconnue, ou réparer du JSON cassé —— un outil navigateur ne demande aucune installation et pas d'échappement shell :

Foire aux questions

Comment pretty-print du JSON avec jq ?

Exécute jq . file.json —— le filtre identity . renvoie l'entrée et jq la formate par défaut. Utilise -c pour une sortie compacte.

Comment extraire un champ unique avec jq ?

Utilise un filtre de chemin comme jq '.data.token', et ajoute -r pour une sortie brute si tu veux la valeur sans les guillemets.

Comment filtrer un tableau JSON avec jq ?

Itère avec .[] et applique select(), par ex. jq '.[] | select(.active == true)'.

jq peut-il valider du JSON ?

Oui —— jq empty file.json parse l'entrée et sort avec un code non nul si elle est invalide, ce qui le rend pratique en CI. Pour les détails voir Comment valider du JSON.

Pour aller plus loin