Aller au contenu

jq Playground · Logs

jq Playground — tester des expressions jq en ligne.

Ni une réimplémentation, ni un aller-retour vers un serveur : le binaire réel de jq 1.8.2, compilé en WebAssembly et exécuté dans cet onglet. Collez votre JSON, écrivez le filtre, et voyez chaque sortie que jq émet — ainsi que l'erreur exacte qu'il afficherait si le filtre est faux.

S’exécute dans votre navigateur — rien de ce que vous collez ne quitte cette page. Comment nous le prouvons

Vrai jq 1.8.2 (WebAssembly) Tourne dans votre navigateur Sans inscription Mis à jour le 31 juil. 2026

jq Playground

Examples
filter.jq program
Flags

-r prints string results without JSON quotes · -s slurps the whole input stream into one array · -n runs the filter once with null as input (read the stream with inputs) · -c prints one line per result instead of pretty-printing.

The version above is read out of the WebAssembly binary at runtime, not written into this page — it is real jq, not a JavaScript re-implementation.

input.json stdin

Results update as you type — press Enter to run now.

Press Esc to release keyboard focus from either editor; /Ctrl + Enter runs and leaves the editor. Nothing you paste is uploaded — jq runs inside this tab.

A jq filter produces a stream of results, not one value: each card below is one output, exactly as jq would print it on its own line. Input is capped at 2 MB, and a filter that never terminates (an unguarded repeat) will freeze this tab until you reload it.

Result

Loading jq — the real binary, compiled to WebAssembly (250–340 KB over the wire, cached after your first visit). The example below runs as soon as it lands.

Le manque

Des builtins inventés — et le serveur de quelqu'un d'autre.

Demandez une ligne de jq à un assistant et vous obtenez quelque chose qui a l'air parfaitement juste et qui échoue au premier essai. L'échec favori est un builtin qui n'existe pas : leaf_paths a disparu de jq 1.8.2, donc jq répond leaf_paths/0 is not defined — et la solution, paths(scalars), n'est pas celle qu'on vous avait donnée. Le même phénomène touche les flags empruntés à jaq et gojq, et les affirmations très assurées sur // qui se cassent discrètement sur 0.

L'autre option est un playground côté serveur, qui fonctionne — en envoyant le JSON que vous vouliez seulement inspecter. Un échange étrange pour la sortie de kubectl get secret, pour une réponse d'API contenant un jeton bearer, ou pour une ligne de log contenant l'adresse e-mail d'un client.

Cette page répond par une vérité vérifiable. Le jq qui tourne ici est le programme C, compilé en WebAssembly, téléchargé une fois depuis ce site et exécuté dans votre onglet — et le badge de version à côté des flags est lu dans ce binaire au lieu d'être tapé dans la page. Chaque résultat de builtin du tableau de référence ci-dessous sort du même binaire et est épinglé par un test : cette page ne peut donc pas s'écarter de ce que jq fait réellement.

Vous travaillez sur des logs plutôt que sur du JSON ? Le testeur de regex pour logs fait le même travail pour les lignes non structurées.

Le déroulé

Comment ça marche.

Quatre étapes, toutes dans l'onglet de votre navigateur — et la troisième est le binaire jq lui-même, pas une imitation.

  1. Télécharger le vrai binaire, une fois.

    jq 1.8.2 en WebAssembly — 907 KB non compressé, de 250 à 340 KB sur le réseau selon l'encodage que négocie votre navigateur — servi depuis ce site comme fichier statique au nom haché et mis en cache par votre navigateur. Il se charge pendant que vous lisez, pas pendant que vous attendez.

  2. Compiler le filtre.

    jq compile votre programme avant de voir la moindre entrée. Une erreur de syntaxe ou une fonction non définie se termine par le code 3 — et vous obtenez le message propre de jq, avec sa ligne, sa colonne et son extrait au caret, pas un « expression invalide ».

  3. L'exécuter sur votre entrée.

    Votre JSON arrive à jq par stdin, avec seulement les flags visibles dans la rangée de flags. jq émet un flux de résultats, et chacun devient sa propre carte — parce qu'un flux de quatre valeurs n'est pas la même réponse qu'un tableau de quatre.

  4. Classer ce qui revient.

    jq utilise le code de sortie 5 pour deux choses : une erreur d'exécution et une entrée impossible à analyser. Les deux sont distinguées ici par le préfixe de stderr et rattachées à l'éditeur qui les produit. Les sorties émises avant l'échec sont conservées, et tout ce que jq a écrit sur stderr est affiché même lorsqu'il termine avec 0.

Par l'exemple

jq peut échouer deux fois et renvoyer quand même 0.

Le code de sortie de jq ne reflète que la DERNIÈRE entrée traitée. Donnez-lui un flux dans lequel deux valeurs cassent le filtre et la dernière non, et une étape de CI qui vérifie $? verra une exécution propre.

Cinq entrées, deux fausses

Un flux de cinq valeurs JSON et le filtre .+1. Les chaînes ne peuvent pas s'ajouter à des nombres : deux des cinq échouent donc.

stdin
1 "x" 2 "y" 3

Trois résultats, deux erreurs, sortie 0

Le playground affiche les trois sorties ET les deux lignes de stderr, et explique pourquoi le code de sortie vaut 0 — déplacez la chaîne à la fin du flux et le même filtre se termine par 5.

results.txt
3 outputs · 3 ms · 2 stderr lines

output 1        2
output 2        3
output 3        4

jq also wrote to stderr                 2 lines
string ("x") and number (1) cannot be added
string ("y") and number (1) cannot be added

Essayez ci-dessus : le panneau de résultats liste les deux lignes de stderr sous « jq also wrote to stderr », avec le code de sortie à côté. Rien n'est caché sous prétexte que jq considère l'exécution comme réussie.

Référence

Les builtins jq que vous utilisez vraiment.

26 filtres, chacun avec une entrée réelle et la sortie exacte que jq 1.8.2 a produite pour elle. Tapez le filtre de n'importe quelle ligne dans le playground ci-dessus et regardez-le tourner sur vos propres données.

Filtre Entrée Sortie — jq 1.8.2
.a.b {"a":{"b":42}} 42 Accès par chemin. Une clé absente vaut null, ce n'est pas une erreur — indexer ce qui n'est pas un objet en est une : .a sur [1,2] échoue avec « Cannot index array with string ».
.items[] | .name {"items":[{"name":"web"},{"name":"api"}]} "web" "api" DEUX sorties, pas un tableau. Enveloppez tout le filtre dans [ … ] si vous en voulez un.
.[] | select(.ms > 100) [{"ms":41},{"ms":998}] {"ms":998} select conserve l'entrée quand la condition est vraie et n'émet rien quand elle est fausse.
map(.ms) [{"ms":41},{"ms":998}] [41,998] map(f) équivaut à [.[] | f] — il prend un tableau et rend un tableau.
keys {"b":1,"a":2} ["a","b"] keys TRIE. Utilisez keys_unsorted pour l'ordre du document — la même entrée donne ["b","a"].
length {"a":1,"b":2} 2 Les clés pour un objet, les éléments pour un tableau, les points de code pour une chaîne (« héllo » vaut 5), la valeur absolue pour un nombre, 0 pour null.
add [1,2,3] 6 Additionne les éléments d'un tableau — ce qui concatène aussi les chaînes et fusionne les objets.
group_by(.k) | map({ k: .[0].k, n: length }) [{"k":"a"},{"k":"a"},{"k":"b"}] [{"k":"a","n":2},{"k":"b","n":1}] L'idiome du comptage par champ. group_by trie d'abord, donc les groupes reviennent dans l'ordre des clés.
unique [3,1,3] [1,3] Trie en plus de dédupliquer. unique_by(f) pour les objets.
sort_by(-.n) [{"n":1},{"n":9}] [{"n":9},{"n":1}] Nier la clé, c'est le tri décroissant ; sort_by n'a pas de flag reverse.
to_entries {"a":1} [{"key":"a","value":1}] Le pont objet ⇄ liste. from_entries fait le retour ; sur un TABLEAU les clés sont les indices.
with_entries(.value += 1) {"a":1,"b":2} {"a":2,"b":3} to_entries | map(f) | from_entries en une seule étape — la façon de mapper sur les valeurs d'un objet.
del(.b) {"a":1,"b":2} {"a":1} Prend un chemin, donc del(.a[1]) et del(.a, .b) fonctionnent aussi.
.a // "fallback" {"a":null} "fallback" Ne se déclenche que sur null, false et « aucune sortie ». {"a":0} donne 0 — zéro est vrai en jq.
has("a") {"a":null} true Interroge la CLÉ, pas la valeur — c'est ainsi qu'on distingue « absente » de « vaut null ».
[paths(scalars)] {"a":{"b":1}} [["a","b"]] Tous les chemins vers une feuille. leaf_paths n'existe plus dans jq 1.8.2 ; ceci le remplace.
flatten [[1,[2]],[3]] [1,2,3] Jusqu'en bas par défaut ; flatten(1) pour un seul niveau.
test("^ERR"; "i") "error: x" true Regex Oniguruma avec une chaîne de flags. match / capture / sub / gsub / splits prennent la même paire.
capture("(?<code>[0-9]{3})") "status 503 here" {"code":"503"} Les groupes nommés deviennent des clés d'objet — le chemin le plus court d'une ligne de log vers des champs.
@csv ["web",3] "web",3 Avec -r. Chaînes entre guillemets, nombres nus, null vide ; un tableau ou objet imbriqué est une erreur d'exécution. @tsv utilise une vraie tabulation.
@base64d "aGVsbG8=" hello Avec -r. Le décodeur de secrets Kubernetes. Un base64 invalide est une erreur d'exécution, pas un silence.
todate 1700000000 2023-11-14T22:13:20Z fromdate fait le retour. strftime("%Y-%m-%d") pour tout autre format.
limit(2; .[]) [1,2,3] 1 2 Arrête le générateur après n sorties — c'est aussi le garde-fou qui rend sûr un filtre sans limite.
.[1:3] [1,2,3,4] [2,3] Découpe tableaux et chaînes ; .[-1:] prend le dernier élément.
.. | numbers {"a":[1,2]} 1 2 .. est la descente récursive ; numbers / strings / objects / arrays / nulls / booleans filtrent par type.
$__loc__ null {"file":"<top-level>","line":1} Où vous êtes dans le programme. Le fichier vaut « <top-level> » — pas « <stdin> », quoi qu'en dise une autocomplétion.

Les sorties sont montrées telles que jq les écrit avec -c ; les lignes @csv, @base64d et todate supposent -r, car sans lui jq écrit le résultat comme une chaîne JSON entre guillemets.

Étape suivante

Votre entrée est en YAML ? Convertissez-la d'abord.

jq lit du JSON, et un manifeste Kubernetes ou une configuration de CI est en YAML. Passez-le par le convertisseur JSON ↔ YAML — qui signale en plus chaque commentaire, chaque ancre et chaque horodatage que la conversion coûte — puis ramenez le JSON ici pour le découper.

results.txt
4 outputs · -r · 3 ms
output 1        web-7d9f8c-2xk4t
output 2        web-7d9f8c-9pl2m
output 3        api-5b4c7d-qq8rn
output 4        batch-1a2b3c-zzz01

FAQ

Vos questions, nos réponses.

Appuyez sur une question pour afficher la réponse.

C'est le vrai jq. La page charge jq 1.8.2 compilé en WebAssembly — le programme C réel, 907 KB non compressé et de 250 à 340 KB sur le réseau, selon que votre navigateur négocie brotli ou gzip — et y fait passer votre filtre. Le badge de version affiché à côté des flags est lu dans ce binaire au moment de l'exécution, il n'est pas écrit dans la page : il ne peut donc pas devenir obsolète. Rien ici n'approxime le comportement de jq, parce que rien ici ne le réimplémente : le même code que sur votre portable tourne dans votre onglet.

Non. Il n'y a ni serveur, ni API, ni journalisation. jq est téléchargé une seule fois depuis ce site comme fichier statique, puis s'exécute entièrement dans votre onglet — c'est exactement la différence avec un playground côté serveur : avec jqplay.org et ses semblables, le JSON que vous collez part vers la machine de quelqu'un d'autre pour y être évalué. Vous pouvez coller ici sans crainte des sorties kubectl de production, des réponses d'API contenant des jetons et des lignes de log contenant des données clients.

Quatre interrupteurs : -r (sortie de chaînes brute), -s (rassembler tout le flux d'entrée dans un tableau), -n (exécuter une fois avec null en entrée) et -c (compact, une ligne par résultat). Absents de cette version : --arg et --argjson, le chargement de modules (-L, include, import — jq répond « module not found »), --seq, la sortie en couleur, les arguments de fichier et la lecture depuis une URL. --arg peut être remplacé dans le programme lui-même : ("prod") as $ns | … lie une valeur de la même façon.

Le plus souvent parce qu'il utilise un builtin qui n'existe pas dans jq 1.8.2. leaf_paths est le cas classique — il a été supprimé, et jq répond « leaf_paths/0 is not defined » ; l'écriture qui fonctionne est paths(scalars). Il en va de même pour les flags inventés et pour les builtins d'autres outils (jaq, gojq, JMESPath) qui n'ont jamais existé dans jq. Une erreur de compilation cite ici le message propre de jq, avec sa ligne, sa colonne et son extrait au caret : vous voyez exactement quel token a été refusé au lieu de le deviner.

-s lit toutes les valeurs du flux d'entrée dans un seul tableau et exécute votre filtre une fois sur ce tableau : 1 2 3 devient [1,2,3]. -n exécute le filtre une fois avec null en entrée et vous remet le flux via le générateur inputs, donc [inputs] sur 1 2 3 donne aussi [1,2,3] — mais c'est vous qui décidez quand chaque valeur est tirée, et c'est ce qui permet d'apparier des valeurs, de sauter un enregistrement d'en-tête ou de s'arrêter tôt. -s met tout en mémoire d'abord ; -n avec inputs travaille en flux.

Parce que -r ne retire que les guillemets autour des résultats qui sont des chaînes. Tout ce qui n'est pas une chaîne — un objet, un tableau, un nombre, un booléen ou null — reste affiché en JSON, et c'est pourquoi . sur {"a":1} est identique avec et sans -r. Si vous voulez du texte à partir d'autre chose qu'une chaîne, convertissez-le dans le filtre : tostring, @csv, @tsv, join(",") ou une chaîne interpolée comme "\(.name) → \(.image)".

Construisez un tableau par ligne et passez-le dans @csv ou @tsv, puis activez -r pour que la ligne soit écrite en texte et non en chaîne JSON entre guillemets. ["web",3] | @csv donne "web",3 — chaînes entre guillemets, nombres nus — et @tsv donne web, puis une vraie tabulation, puis 3. Les deux refusent les valeurs imbriquées : un tableau ou un objet dans une ligne est une erreur d'exécution (« array ([\"a\"]) is not valid in a csv row »), et null devient un champ vide.

a // b produit a, sauf si a vaut false, null, ou ne produit aucune sortie — dans ce cas il produit b. Le piège : cela ne veut pas dire « si vide ». En jq, 0 et la chaîne vide sont vrais, donc {"a":0} | .a // "fallback" donne 0 et non "fallback". Si vous voulez vraiment dire « quand la clé est absente », demandez-le : if has("a") then .a else "fallback" end.

Pas tant que la valeur reste intacte. jq 1.8 conserve le littéral que vous avez fourni : {"n":9007199254740993} | .n affiche exactement 9007199254740993 — un nombre que JavaScript ne peut pas représenter — et 1.0 reste 1.0 au lieu de se réduire à 1. Dès que vous faites un calcul dessus, la garantie s'arrête : .n + 0 devient 9007199254740992, parce que le calcul passe par un double 64 bits. C'est une propriété de jq, pas du navigateur ; jq en ligne de commande répond la même chose.

L'entrée est plafonnée à 2 MB (2 000 000 d'octets) et le panneau de résultats affiche les 200 premières sorties, toujours avec le nombre réel à côté — « Copy all » copie quand même tout. Un filtre qui ne se termine jamais est la seule chose qui fasse vraiment mal : jq s'exécute de façon synchrone dans cet onglet, il bloque donc la page jusqu'au rechargement. Obtenir une carte d'erreur à la place dépend de la forme. Si le flux infini est collecté — [repeat(1)], [recurse(.a)], length, last —, jq remplit sa mémoire WebAssembly et s'interrompt au bout d'une à deux secondes, et le playground en fait un message d'erreur ordinaire. S'il ne fait que couler, un repeat(1) ou un recurse(.a) nus continuent : nous avons mesuré 40 secondes sans aucune interruption. Les deux formes à surveiller sont un repeat sans garde-fou et recurse(.field), qui arrive sur null puis récurse sur null indéfiniment — écrivez recurse(.field?; . != null), ou enveloppez le générateur dans limit(n; …).

More free, private DevOps tools.

Le jq Playground est l'un des outils de OpsCanopy — une canopée grandissante de validateurs, convertisseurs et testeurs qui tournent dans le navigateur et ne touchent jamais un serveur.

39 outils gratuits, tous utilisables hors ligne — opscanopy.com fonctionne sans inscription et sans rien téléverser.

À voir aussi : le testeur de regex pour logs pour les lignes qui ne sont pas encore du JSON, le convertisseur JSON ↔ YAML pour transformer un manifeste en quelque chose que jq peut lire, et le décodeur de JWT quand le JSON intéressant se trouve dans un jeton — ou parcourez le répertoire des outils complet.

Fourni tel quel, pour votre commodité ; jq est un projet open source distinct et cette page n'y est pas affiliée. OpsCanopy est gratuit et ouvert.