jq Playground · Logs
jq Playground — jq-Ausdrücke online testen.
Keine Neuimplementierung und kein Umweg über einen Server: die echte jq-1.8.2-Binary, übersetzt nach WebAssembly und ausgeführt in diesem Tab. Fügen Sie Ihr JSON ein, schreiben Sie den Filter, und sehen Sie jede Ausgabe, die jq erzeugt — samt der exakten Fehlermeldung, die es ausgeben würde, wenn der Filter falsch ist.
Läuft in Ihrem Browser — nichts, was Sie einfügen, verlässt diese Seite. Wie wir das belegen
jq Playground
-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.
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.
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.
Die Lücke
Erfundene Builtins — und der Server eines Fremden.
Fragen Sie einen Assistenten nach einem jq-Einzeiler, und Sie bekommen etwas, das genau richtig aussieht und beim ersten Lauf scheitert. Der beliebteste Fehler ist ein Builtin, das es nicht gibt: leaf_paths ist aus jq 1.8.2 verschwunden, jq antwortet also leaf_paths/0 is not defined — und die Lösung, paths(scalars), war nicht das, was man Ihnen gesagt hat. Dasselbe passiert mit Flags, die von jaq und gojq geliehen sind, und mit selbstbewussten Aussagen über //, die bei 0 still auseinanderfallen.
Die Alternative ist ein serverseitiger Playground. Der funktioniert — indem er das JSON hochlädt, das Sie eigentlich nur ansehen wollten. Ein merkwürdiger Tausch für die Ausgabe von kubectl get secret, für eine API-Antwort mit einem Bearer-Token darin oder für eine Logzeile mit der E-Mail-Adresse eines Kunden.
Diese Seite antwortet stattdessen mit belegbarer Wahrheit. Das jq, das hier läuft, ist das C-Programm, übersetzt nach WebAssembly, einmal von dieser Seite geladen und in Ihrem Tab ausgeführt — und das Versions-Badge neben den Flags wird aus dieser Binary gelesen statt in die Seite getippt. Jedes Builtin-Ergebnis in der Referenztabelle unten stammt aus derselben Binary und ist durch einen Test festgenagelt; diese Seite kann sich also nicht von dem entfernen, was jq tatsächlich tut.
Sie arbeiten mit Logs statt mit JSON? Der Regex Log Tester macht dasselbe für unstrukturierte Zeilen.
Die Pipeline
So funktioniert es.
Vier Schritte, alle in Ihrem Browser-Tab — und der dritte ist die tatsächliche jq-Binary, keine Nachahmung.
-
Die echte Binary holen — einmal.
jq 1.8.2 als WebAssembly — 907 KB unkomprimiert, 250–340 KB über die Leitung, abhängig von der Kodierung, die Ihr Browser aushandelt — ausgeliefert von dieser Seite als statische Datei mit Hash im Namen und vom Browser zwischengespeichert. Sie lädt, während Sie lesen, nicht während Sie warten.
-
Den Filter kompilieren.
jq kompiliert Ihr Programm, bevor es irgendeine Eingabe sieht. Ein Syntaxfehler oder eine undefinierte Funktion endet mit Exit 3 — und Sie bekommen jq eigene Meldung samt Zeile, Spalte und Caret-Auszug, nicht „ungültiger Ausdruck“.
-
Über der Eingabe ausführen.
Ihr JSON geht über stdin an jq, mit genau den Flags aus der Flag-Zeile. jq erzeugt einen Strom von Ergebnissen, und jedes bekommt seine eigene Karte — denn ein Strom aus vier Werten ist nicht dieselbe Antwort wie ein Array mit vier Werten.
-
Einordnen, was zurückkommt.
jq nutzt Exit-Code 5 doppelt: für einen Laufzeitfehler und für eine nicht parsebare Eingabe. Beide werden hier am stderr-Präfix unterschieden und dem Editor zugeordnet, der sie verursacht hat. Ausgaben vor einem Fehler bleiben erhalten, und alles, was jq nach stderr geschrieben hat, wird auch bei Exit 0 gezeigt.
Am Beispiel
jq kann zweimal scheitern und trotzdem 0 zurückgeben.
Der Exit-Code von jq spiegelt nur die LETZTE verarbeitete Eingabe. Geben Sie ihm einen Strom, in dem zwei Werte den Filter brechen und der letzte nicht, dann sieht ein CI-Schritt, der $? prüft, einen sauberen Lauf.
Fünf Eingaben, zwei davon falsch
Ein Strom aus fünf JSON-Werten und der Filter .+1. Strings lassen sich nicht zu Zahlen addieren, zwei von fünf scheitern also.
1 "x" 2 "y" 3 Drei Ergebnisse, zwei Fehler, Exit 0
Der Playground zeigt alle drei Ausgaben UND beide stderr-Zeilen und sagt, warum der Exit-Code 0 ist — verschieben Sie den String an das Ende des Stroms, und derselbe Filter endet mit 5.
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 Probieren Sie es oben aus: das Ergebnisfeld listet beide stderr-Zeilen unter „jq also wrote to stderr“, mit dem Exit-Code daneben. Nichts wird verschwiegen, nur weil jq den Lauf für einen Erfolg hält.
Referenz
Die jq-Builtins, die Sie wirklich benutzen.
26 Filter, jeder mit einer echten Eingabe und der exakten Ausgabe, die jq 1.8.2 dafür erzeugt hat. Tippen Sie den Filter einer Zeile oben in den Playground und sehen Sie ihn auf Ihren eigenen Daten laufen.
| Filter | Eingabe | Ausgabe — jq 1.8.2 |
|---|---|---|
| .a.b | {"a":{"b":42}} | 42 Pfadzugriff. Ein fehlender Schlüssel ist null, kein Fehler — der Zugriff auf ein Nicht-Objekt schon: .a auf [1,2] scheitert mit „Cannot index array with string“. |
| .items[] | .name | {"items":[{"name":"web"},{"name":"api"}]} | "web" "api" ZWEI Ausgaben, kein Array. Setzen Sie den ganzen Filter in [ … ], wenn Sie eines wollen. |
| .[] | select(.ms > 100) | [{"ms":41},{"ms":998}] | {"ms":998} select behält die Eingabe, wenn die Bedingung wahr ist, und erzeugt nichts, wenn sie falsch ist. |
| map(.ms) | [{"ms":41},{"ms":998}] | [41,998] map(f) ist [.[] | f] — es nimmt ein Array und liefert ein Array. |
| keys | {"b":1,"a":2} | ["a","b"] keys SORTIERT. Für die Dokumentreihenfolge nehmen Sie keys_unsorted — dieselbe Eingabe ergibt dann ["b","a"]. |
| length | {"a":1,"b":2} | 2 Schlüssel bei einem Objekt, Elemente bei einem Array, Code-Points bei einem String („héllo“ ist 5), Absolutwert bei einer Zahl, 0 bei null. |
| add | [1,2,3] | 6 Addiert die Elemente eines Arrays — verkettet damit auch Strings und führt Objekte zusammen. |
| group_by(.k) | map({ k: .[0].k, n: length }) | [{"k":"a"},{"k":"a"},{"k":"b"}] | [{"k":"a","n":2},{"k":"b","n":1}] Das Idiom zum Zählen pro Feld. group_by sortiert zuerst, die Gruppen kommen also in Schlüsselreihenfolge zurück. |
| unique | [3,1,3] | [1,3] Sortiert zusätzlich zum Entfernen von Duplikaten. Für Objekte: unique_by(f). |
| sort_by(-.n) | [{"n":1},{"n":9}] | [{"n":9},{"n":1}] Den Schlüssel zu negieren ist die absteigende Sortierung; sort_by hat kein reverse-Flag. |
| to_entries | {"a":1} | [{"key":"a","value":1}] Die Brücke Objekt ⇄ Liste. from_entries geht zurück; bei einem ARRAY sind die Schlüssel die Indizes. |
| with_entries(.value += 1) | {"a":1,"b":2} | {"a":2,"b":3} to_entries | map(f) | from_entries in einem Schritt — so mappt man über die Werte eines Objekts. |
| del(.b) | {"a":1,"b":2} | {"a":1} Nimmt einen Pfad, deshalb funktionieren auch del(.a[1]) und del(.a, .b). |
| .a // "fallback" | {"a":null} | "fallback" Greift nur bei null, false und „keine Ausgabe“. {"a":0} ergibt 0 — die Null ist in jq wahr. |
| has("a") | {"a":null} | true Fragt nach dem SCHLÜSSEL, nicht nach dem Wert — so unterscheidet man „fehlt“ von „ist null“. |
| [paths(scalars)] | {"a":{"b":1}} | [["a","b"]] Jeder Pfad zu einem Blatt. leaf_paths existiert in jq 1.8.2 nicht mehr; das hier ist der Ersatz. |
| flatten | [[1,[2]],[3]] | [1,2,3] Standardmäßig bis nach unten; flatten(1) für eine Ebene. |
| test("^ERR"; "i") | "error: x" | true Oniguruma-Regex mit Flag-String. match / capture / sub / gsub / splits nehmen dasselbe Paar. |
| capture("(?<code>[0-9]{3})") | "status 503 here" | {"code":"503"} Benannte Gruppen werden Objektschlüssel — der schnellste Weg von einer Logzeile zu Feldern. |
| @csv | ["web",3] | "web",3 Mit -r. Strings quotiert, Zahlen nackt, null leer; ein verschachteltes Array oder Objekt ist ein Laufzeitfehler. @tsv nutzt einen echten Tabulator. |
| @base64d | "aGVsbG8=" | hello Mit -r. Der Kubernetes-Secret-Dekoder. Ungültiges Base64 ist ein Laufzeitfehler, kein Schweigen. |
| todate | 1700000000 | 2023-11-14T22:13:20Z fromdate geht zurück. Für jedes andere Format: strftime("%Y-%m-%d"). |
| limit(2; .[]) | [1,2,3] | 1 2 Stoppt den Generator nach n Ausgaben — und ist damit auch die Bremse, die einen unbegrenzten Filter sicher macht. |
| .[1:3] | [1,2,3,4] | [2,3] Schneidet Arrays und Strings; .[-1:] nimmt das letzte Element. |
| .. | numbers | {"a":[1,2]} | 1 2 .. ist der rekursive Abstieg; numbers / strings / objects / arrays / nulls / booleans filtern nach Typ. |
| $__loc__ | null | {"file":"<top-level>","line":1} Wo Sie im Programm stehen. Die Datei ist „<top-level>“ — nicht „<stdin>“, was auch immer eine Autovervollständigung behauptet. |
Die Ausgaben sind so gezeigt, wie jq sie mit -c ausgibt; die Zeilen zu @csv, @base64d und todate setzen -r voraus, weil jq das Ergebnis sonst als quotierten JSON-String ausgibt.
Nächster Schritt
Ihre Eingabe ist YAML? Erst konvertieren.
jq liest JSON, ein Kubernetes-Manifest oder eine CI-Konfiguration ist YAML. Schicken Sie es durch den JSON ↔ YAML Konverter — der zusätzlich jeden Kommentar, jeden Anker und jeden Zeitstempel meldet, den die Konvertierung kostet — und bringen Sie das JSON dann hierher zurück.
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
Fragen, beantwortet.
Tippen Sie auf eine Frage, um die Antwort aufzuklappen.
Ist das echtes jq oder eine JavaScript-Neuimplementierung?
Es ist echtes jq. Die Seite lädt jq 1.8.2, übersetzt nach WebAssembly — das tatsächliche C-Programm, 907 KB unkomprimiert und 250–340 KB über die Leitung, je nachdem ob Ihr Browser Brotli oder gzip aushandelt — und führt Ihren Filter damit aus. Das Versions-Badge neben den Flags wird zur Laufzeit aus dieser Binary gelesen und nicht in die Seite geschrieben, es kann also nicht veralten. Hier wird nichts an jq angenähert, weil hier nichts an jq nachgebaut wird: derselbe Code, der auf Ihrem Laptop läuft, läuft in Ihrem Tab.
Verlässt mein JSON jemals meinen Browser?
Nein. Es gibt keinen Server, keine API und kein Logging. jq wird einmal als statische Datei von dieser Seite geladen und läuft danach vollständig in Ihrem Tab — genau darin liegt der Unterschied zu einem serverseitigen Playground: bei jqplay.org und ähnlichen Diensten wird das eingefügte JSON zur Auswertung an einen fremden Rechner geschickt. Sie können hier bedenkenlos Produktions-Ausgaben von kubectl, API-Antworten mit Tokens und Logzeilen mit Kundendaten einfügen.
Welche Flags stehen zur Verfügung — und welche nicht?
Vier Schalter: -r (rohe String-Ausgabe), -s (den Eingabe-Stream in ein Array einsammeln), -n (einmal mit null als Eingabe laufen) und -c (kompakt, eine Zeile pro Ergebnis). Nicht enthalten in dieser Version: --arg und --argjson, das Laden von Modulen (-L, include, import — jq antwortet „module not found“), --seq, farbige Ausgabe, Dateiargumente und das Laden von einer URL. --arg lässt sich im Programm selbst ersetzen: ("prod") as $ns | … bindet einen Wert genauso.
Warum scheitert das jq, das ein KI-Assistent geschrieben hat?
Meist, weil ein verwendetes Builtin in jq 1.8.2 nicht existiert. leaf_paths ist der Klassiker — es wurde entfernt, und jq antwortet „leaf_paths/0 is not defined“; die funktionierende Schreibweise ist paths(scalars). Dasselbe passiert mit erfundenen Flags und mit Builtins aus anderen Werkzeugen (jaq, gojq, JMESPath), die es in jq nie gab. Ein Compile-Fehler zeigt hier jq eigene Meldung samt Zeile, Spalte und Caret-Auszug — Sie sehen also genau, welches Token abgelehnt wurde, statt zu raten.
Was ist der Unterschied zwischen -s und inputs?
-s liest jeden Wert des Eingabe-Streams in ein einzelnes Array und führt Ihren Filter einmal darauf aus: aus 1 2 3 wird [1,2,3]. -n führt den Filter einmal mit null als Eingabe aus und übergibt Ihnen den Stream über den Generator inputs — [inputs] ergibt bei 1 2 3 ebenfalls [1,2,3], aber Sie steuern, wann jeder Wert geholt wird. Genau das erlaubt es, Werte zu paaren, einen Kopfsatz zu überspringen oder früh abzubrechen. -s puffert erst alles, -n mit inputs streamt.
Warum gibt -r bei meinem Objekt weiterhin JSON aus?
Weil -r nur die Anführungszeichen um String-Ergebnisse entfernt. Alles, was kein String ist — Objekt, Array, Zahl, Boolean oder null — wird weiterhin als JSON ausgegeben. Deshalb sieht . bei {"a":1} mit und ohne -r identisch aus. Wenn Sie Text aus einem Nicht-String brauchen, wandeln Sie ihn im Filter um: tostring, @csv, @tsv, join(",") oder ein interpolierter String wie "\(.name) → \(.image)".
Wie bekomme ich CSV oder TSV aus jq heraus?
Bauen Sie pro Zeile ein Array und schicken Sie es durch @csv oder @tsv, und schalten Sie dann -r ein, damit die Zeile als Text und nicht als quotierter JSON-String ausgegeben wird. ["web",3] | @csv ergibt "web",3 — Strings quotiert, Zahlen nackt — und @tsv ergibt web, dann einen echten Tabulator, dann 3. Beide verweigern verschachtelte Werte: ein Array oder Objekt innerhalb einer Zeile ist ein Laufzeitfehler („array ([\"a\"]) is not valid in a csv row“), und null wird ein leeres Feld.
Was macht // tatsächlich?
a // b liefert a — außer a ist false, null, oder erzeugt überhaupt keine Ausgabe; dann liefert es b. Die Falle: es bedeutet nicht „wenn leer“. 0 und der leere String sind in jq wahr, deshalb ergibt {"a":0} | .a // "fallback" die 0 und nicht "fallback". Wenn Sie wirklich „wenn der Schlüssel fehlt“ meinen, fragen Sie danach: if has("a") then .a else "fallback" end.
Rundet jq große Zahlen so wie JavaScript?
Nicht, solange der Wert unberührt bleibt. jq 1.8 bewahrt das Literal, das Sie übergeben haben: {"n":9007199254740993} | .n gibt exakt 9007199254740993 aus — eine Zahl, die JavaScript nicht darstellen kann — und 1.0 bleibt 1.0, statt zu 1 zu werden. Sobald Sie damit rechnen, endet die Garantie: .n + 0 wird 9007199254740992, weil die Rechnung durch einen 64-Bit-Double läuft. Das ist eine Eigenschaft von jq, nicht des Browsers; jq auf der Kommandozeile antwortet genauso.
Wie groß darf die Eingabe sein — und was, wenn mein Filter nie endet?
Die Eingabe ist auf 2 MB (2.000.000 Bytes) begrenzt, und das Ergebnisfeld zeigt die ersten 200 Ausgaben, immer mit der echten Gesamtzahl daneben — „Copy all“ kopiert weiterhin alle. Ein Filter, der nie endet, ist das Einzige, was wirklich weh tut: jq läuft synchron in diesem Tab und blockiert die Seite, bis Sie neu laden. Ob Sie stattdessen eine Fehlerkarte sehen, hängt von der Form ab. Wird der endlose Strom gesammelt — [repeat(1)], [recurse(.a)], length, last —, füllt jq seinen WebAssembly-Speicher und bricht nach ein bis zwei Sekunden ab, und der Playground macht daraus eine normale Fehlermeldung. Strömt er einfach weiter, läuft ein nacktes repeat(1) oder recurse(.a) unbegrenzt: nach 40 Sekunden haben wir keinen Abbruch gemessen. Auf diese zwei Formen sollten Sie achten: ein ungebremstes repeat und recurse(.field), das auf null läuft und dann für immer auf null weiterrekursiert — schreiben Sie recurse(.field?; . != null) oder verpacken Sie den Generator in limit(n; …).
More free, private DevOps tools.
Der jq Playground ist eines von vielen Werkzeugen in OpsCanopy — einem wachsenden Dach aus browserbasierten Validatoren, Konvertern und Testern, die niemals einen Server berühren.
39 kostenlose Tools, jedes einzelne offlinefähig — opscanopy.com funktioniert ohne Registrierung, und nichts wird hochgeladen.
Verwandt: der Regex Log Tester für die Logzeilen, die noch kein JSON sind, der JSON ↔ YAML Konverter, um aus einem Manifest etwas zu machen, das jq lesen kann, und der JWT Decoder, wenn das interessante JSON in einem Token steckt — oder durchsuchen Sie das vollständige Tools-Verzeichnis.
Ohne Gewähr zur Verfügung gestellt; jq ist ein eigenständiges Open-Source-Projekt, und diese Seite steht in keiner Verbindung dazu. OpsCanopy ist kostenlos und offen.