jq-Spickzettel: 30 praxiserprobte JSON-Kommandozeilen-Muster
Du pipest kubectl get pods -o json in less, und das Terminal friert an einer zwei Megabyte großen JSON-Wand ein. Du willst nur den Namen jedes Pods in der Phase Running. jq erledigt das mit drei Zeichen Filter-Syntax — sobald du das Vokabular kennst.
Das hier ist keine weitere Syntaxreferenz. Es sind 30 Muster, die du wirklich tippen wirst, gruppiert nach Aufgabe: Zugriff, Filtern, Transformieren, Aggregieren, Formatieren und das Verzahnen mit echten Werkzeugen wie kubectl, aws und docker.
Wann jq, ein Browser-Formatter oder Code?
jq ist nicht immer die richtige Antwort. Ehrlich betrachtet gibt es drei Optionen:
| Situation | Beste Wahl | Warum |
|---|---|---|
| Eine API-Antwort, Syntax-Hervorhebung und Zeilennummern gewünscht | Browser-JSON Formatter | Visuelles Diff, null Setup, im Browser privat |
| Shell-Pipeline, Logverarbeitung, CI-Skript, Remote-Server | jq | Komponierbar, skriptfähig, keine GUI-Abhängigkeit |
| Geschäftslogik, Unit-Tests, komplexe Verzweigungen | Code (JS / Python) | Echter Debugger, Typen, Bibliotheken |
Greif zu jq, wenn die Aufgabe in einer Shell-Pipeline lebt — sonst ist vieles anderswo einfacher.
Installation und deine erste Pipeline
jq kommt als einzelnes Binary auf jeder großen Plattform:
# macOS
brew install jq
# Debian / Ubuntu
sudo apt install jq
# Windows (winget)
winget install jqlang.jq
Erste Pipeline mit dem Identity-Filter:
curl -s https://api.github.com/users/octocat | jq .
Der Filter . gibt seine Eingabe unverändert und hübsch formatiert aus. Das allein ersetzt die meisten „Lass mich dieses JSON im Editor öffnen”-Momente.
Fünf Flags decken 90 % des echten Einsatzes ab:
| Flag | Zweck |
|---|---|
-r | Roh-Ausgabe — entfernt Anführungszeichen um String-Ergebnisse |
-c | Kompakt — ein JSON-Wert pro Zeile (NDJSON) |
-s | Slurp — liest alle Eingaben in ein einziges Array |
-R | Roh-Eingabe — liest Zeilen als Strings statt als JSON |
-n | Null-Eingabe — liest stdin nicht, nutzt null als Eingabe |
Das zentrale Denkmodell: Filter und Pipes
Ein Filter nimmt einen JSON-Wert als Eingabe und erzeugt null oder mehr JSON-Werte als Ausgabe. Filter werden mit einer Pipe | komponiert, die jede Ausgabe des linken Filters als Eingabe an den rechten weitergibt. Es ist dasselbe Denkmodell wie Shell-Pipes, nur dass JSON-Werte fließen statt Bytes.
# . — Identität
echo '{"name":"Alice"}' | jq '.'
# .key — Feldzugriff
echo '{"name":"Alice"}' | jq '.name'
# .key.sub — tiefer Pfad
echo '{"user":{"email":"a@x.com"}}' | jq '.user.email'
# .[] — Array-Elemente iterieren (erzeugt mehrere Ausgaben)
echo '[{"id":1},{"id":2}]' | jq '.[] | .id'
# Pipe-Komposition: jede Ausgabe von .items[] fließt in .name
echo '{"items":[{"name":"a"},{"name":"b"}]}' | jq '.items[] | .name'
Das ist die gesamte Grammatik. Die 30 Muster unten sind Kombinationen dieser Primitive.
30 Muster, die du wirklich brauchst
Jedes Muster zeigt Eingabe-JSON, Kommando und Ausgabe. Kopiere beliebige in dein Terminal.
Zugriff und Extraktion (Muster 1–5)
Muster 1 — Sicherer Zugriff mit ?
Auf ein Feld zugreifen, das vielleicht fehlt, ohne zu crashen:
echo '{"name":"Alice"}' | jq '.address?.city?'
# Ausgabe: null
Das ? unterdrückt Fehler bei fehlenden Schlüsseln. Ohne es würde .address.city einen Typfehler werfen, wenn .address fehlt.
Muster 2 — Zugriff über tiefen Pfad
echo '{"user":{"profile":{"email":"a@x.com"}}}' | jq '.user.profile.email'
# Ausgabe: "a@x.com"
Muster 3 — Array-Slicing
echo '[10,20,30,40,50]' | jq '.[1:3]'
# Ausgabe: [20, 30]
echo '[10,20,30,40,50]' | jq '.[-1]'
# Ausgabe: 50
Negative Indizes zählen vom Ende her. Slices nutzen halboffene Intervalle wie in Python.
Muster 4 — Rekursiver Abstieg zum Finden aller passenden Schlüssel
echo '{"a":{"name":"x"},"b":[{"name":"y"},{"id":1}]}' | jq '.. | .name? | select(. != null)'
# Ausgabe: "x"
# "y"
.. wandert durch jeden Wert im Baum. Mit .name? und select kombiniert extrahiert es jedes name-Feld unabhängig von der Tiefe — unverzichtbar beim Erkunden unbekannter JSON-Schemata.
Muster 5 — Alle Schlüssel eines Objekts auflisten
echo '{"zebra":1,"apple":2,"mango":3}' | jq 'keys'
# Ausgabe: ["apple", "mango", "zebra"]
echo '{"zebra":1,"apple":2,"mango":3}' | jq 'keys_unsorted'
# Ausgabe: ["zebra", "apple", "mango"]
keys sortiert alphabetisch; keys_unsorted bewahrt die Einfügereihenfolge.
Filtern (Muster 6–10)
Muster 6 — Array nach Bedingung filtern
echo '[{"age":20},{"age":30},{"age":40}]' | jq 'map(select(.age > 25))'
# Ausgabe: [{"age":30},{"age":40}]
map(f) wendet f auf jedes Element an; select(cond) behält nur Elemente, für die die Bedingung wahr ist.
Muster 7 — String-Präfix-Abgleich
echo '[{"name":"api-gateway"},{"name":"web-ui"},{"name":"api-auth"}]' \
| jq '.[] | select(.name | startswith("api"))'
# Ausgabe: {"name":"api-gateway"}
# {"name":"api-auth"}
Ebenfalls nützlich: endswith("..."), contains("..."), test("^regex$").
Muster 8 — Kombinierte Bedingungen
echo '[{"type":"A","count":5},{"type":"A","count":15},{"type":"B","count":20}]' \
| jq '.[] | select(.type == "A" and .count > 10)'
# Ausgabe: {"type":"A","count":15}
and, or, not verhalten sich wie erwartet.
Muster 9 — Sensible Felder löschen
echo '{"user":"alice","password":"s3cret","token":"abc"}' | jq 'del(.password, .token)'
# Ausgabe: {"user":"alice"}
del() akzeptiert mehrere Pfade und ist unkritisch, wenn einer fehlt.
Muster 10 — Nach Feld deduplizieren
echo '[{"id":1,"v":"a"},{"id":2,"v":"b"},{"id":1,"v":"a2"}]' | jq 'unique_by(.id)'
# Ausgabe: [{"id":1,"v":"a"},{"id":2,"v":"b"}]
unique dedupliziert ganze Werte; unique_by(f) dedupliziert nach dem Ergebnis eines Filters.
Transformieren (Muster 11–15)
Muster 11 — Felder umbenennen
echo '[{"first_name":"Alice","age":30}]' | jq 'map({name: .first_name, age})'
# Ausgabe: [{"name":"Alice","age":30}]
Die Kurzform {age} entspricht {age: .age}.
Muster 12 — Berechnetes Feld mit String-Interpolation hinzufügen
echo '[{"first":"Alice","last":"Chen"}]' \
| jq 'map(. + {fullName: "\(.first) \(.last)"})'
# Ausgabe: [{"first":"Alice","last":"Chen","fullName":"Alice Chen"}]
\(expr) wertet expr aus und fügt den Wert in den String ein.
Muster 13 — Verschachtelte Arrays abflachen
echo '[{"tags":["a","b"]},{"tags":["c"]}]' | jq '[.[] | .tags[]]'
# Ausgabe: ["a","b","c"]
echo '[[1,2],[3,[4,5]]]' | jq 'flatten'
# Ausgabe: [1,2,3,4,5]
flatten nimmt ein optionales Tiefen-Argument: flatten(1) schält nur eine Ebene ab.
Muster 14 — Objekt in Array und zurück
echo '{"a":1,"b":2}' | jq 'to_entries'
# Ausgabe: [{"key":"a","value":1},{"key":"b","value":2}]
echo '[{"key":"a","value":1},{"key":"b","value":2}]' | jq 'from_entries'
# Ausgabe: {"a":1,"b":2}
Dieses Paar ermöglicht Transformationen, die über Objektschlüssel iterieren — was die Punkt-Syntax direkt nicht kann.
Muster 15 — Zwei Objekte tief zusammenführen
echo '{"a":{"x":1},"b":2}' | jq '. * {a:{y:9}, c:3}'
# Ausgabe: {"a":{"x":1,"y":9},"b":2,"c":3}
Der *-Operator macht eine tiefe Zusammenführung. Für flaches Mergen + (die rechte Seite gewinnt).
Aggregieren (Muster 16–20)
Muster 16 — Länge von Arrays, Objekten und Strings
echo '[1,2,3,4]' | jq 'length' # 4
echo '{"a":1,"b":2}' | jq 'length' # 2
echo '"hello"' | jq 'length' # 5
Muster 17 — Feld summieren
echo '[{"price":10},{"price":25},{"price":5}]' | jq '[.[].price] | add'
# Ausgabe: 40
add summiert Zahlen, verkettet Strings oder führt Arrays zusammen — je nach Eingabetyp.
Muster 18 — Nach Feld gruppieren
echo '[{"cat":"A","n":1},{"cat":"B","n":2},{"cat":"A","n":3}]' | jq 'group_by(.cat)'
# Ausgabe: [[{"cat":"A","n":1},{"cat":"A","n":3}],[{"cat":"B","n":2}]]
Jede Gruppe wird zu einem inneren Array. Mit map kombinieren, um pro Gruppe zu aggregieren.
Muster 19 — Absteigend sortieren
echo '[{"date":"2026-01-03"},{"date":"2026-01-01"},{"date":"2026-01-02"}]' \
| jq 'sort_by(.date) | reverse'
# Ausgabe: [{"date":"2026-01-03"},{"date":"2026-01-02"},{"date":"2026-01-01"}]
ISO-8601-Datumsstrings sortieren als Strings korrekt. Andere Formate vorher parsen — der Unix-Zeitstempel-Leitfaden deckt Epochensekunden, Millisekunden und Zeitzonen-Konvertierung ausführlich ab.
Muster 20 — Maximum oder Minimum nach Feld
echo '[{"name":"a","rating":4.1},{"name":"b","rating":4.8},{"name":"c","rating":3.9}]' \
| jq 'max_by(.rating)'
# Ausgabe: {"name":"b","rating":4.8}
min_by, max_by liefern ein einzelnes Element. Top N per sort_by(.rating) | reverse | .[:N].
Ausgabe formatieren (Muster 21–25)
Muster 21 — CSV-Ausgabe
echo '[{"name":"Alice","age":30},{"name":"Bob","age":25}]' \
| jq -r '.[] | [.name, .age] | @csv'
# Ausgabe: "Alice",30
# "Bob",25
@csv setzt Anführungszeichen um Strings und escapet interne Anführungszeichen. -r entfernt die äußeren JSON-String-Anführungszeichen, damit das CSV direkt weiterpipebar ist. Für die vollständige Konvertierung zwischen CSV und JSON in Pipelines siehe den CSV-zu-JSON-Konvertierungsleitfaden.
Muster 22 — TSV-Ausgabe
echo '[{"id":1,"name":"Alice"},{"id":2,"name":"Bob"}]' \
| jq -r '.[] | [.id, .name] | @tsv'
# Ausgabe: 1 Alice
# 2 Bob
Tab-getrennte Ausgabe versteht sich bestens mit cut, awk und column -t.
Muster 23 — Rohe String-Ausgabe
echo '["alpha","beta"]' | jq -r '.[]'
# Ausgabe: alpha
# beta
Ohne -r hätte jede Zeile umschließende Anführungszeichen. Roh-Ausgabe ist das, was du an xargs, while read oder einen anderen Shell-Befehl weiterreichst.
Muster 24 — NDJSON / JSON Lines
echo '[{"a":1},{"a":2}]' | jq -c '.[]'
# Ausgabe: {"a":1}
# {"a":2}
Jede Zeile ist ein eigenständiger JSON-Wert — das Format, das Kafka, Elasticsearch und die meisten strukturierten Logger nutzen. -c entfernt zusätzlich jeglichen internen Whitespace.
Muster 25 — String-Interpolation für formatierte Ausgabe
echo '[{"name":"server-1","cpu":0.73},{"name":"server-2","cpu":0.21}]' \
| jq -r '.[] | "\(.name): \(.cpu * 100)% CPU"'
# Ausgabe: server-1: 73% CPU
# server-2: 21% CPU
Ideal für Zusammenfassungen und Log-Zeilen, wo rohes JSON Rauschen wäre.
DevOps im Alltag (Muster 26–30)
Muster 26 — kubectl: Namen jedes laufenden Pods
kubectl get pods -o json \
| jq -r '.items[] | select(.status.phase=="Running") | .metadata.name'
Pipeline: Pods iterieren, nur Running behalten, Namen als Roh-String ausgeben.
Muster 27 — AWS EC2: Instanz-IDs mit öffentlicher IP
aws ec2 describe-instances \
| jq -r '.Reservations[].Instances[] | [.InstanceId, .PublicIpAddress // "none"] | @tsv'
Der Alternativ-Operator // liefert einen Fallback, wenn das Feld null ist — verhindert ein wörtliches null in der Ausgabespalte.
Muster 28 — GitHub API: paginierte Ergebnisse zusammenführen
for p in 1 2 3; do
curl -s "https://api.github.com/orgs/myorg/repos?per_page=100&page=$p"
done | jq -s 'add | map(.name)'
-s schlürft alle Antworten in ein Array-von-Arrays, add hängt sie aneinander, map(.name) extrahiert Namen. Ein gängiges Muster für jede paginierte API.
Muster 29 — Strukturierte Log-Dateien filtern
cat app.log | jq -c 'select(.level=="error")'
Setzt voraus, dass die Log-Datei NDJSON ist (ein JSON-Objekt pro Zeile). Mit tail -f für Live-Monitoring kombinieren:
tail -f app.log | jq -c 'select(.level=="error") | {ts: .timestamp, msg: .message}'
Muster 30 — Docker: alle verwendeten Image-Namen
docker inspect $(docker ps -q) | jq -r '.[].Config.Image' | sort -u
Nützlich, um schnell zu prüfen, welche Image-Versionen auf einem Host laufen.
Häufige Fehler und ihre Lösungen
Jeder jq-Nutzer stolpert über diese. Vorab die Lösung zu kennen spart Stunden.
Cannot iterate over null (null)
Das Eingabefeld, über das du iterieren wolltest, war null oder fehlte. Zwei Lösungen:
# Variante A: optionaler Operator
echo '{}' | jq '.items[]?'
# Ausgabe: (nichts, kein Fehler)
# Variante B: Alternativ-Operator mit Default
echo '{}' | jq '(.items // [])[]'
# Ausgabe: (nichts, kein Fehler)
? nutzen, um stumm zu überspringen. // [] nutzen, um ein konkretes leeres Array zu erzwingen, damit nachfolgende Filter weiterlaufen.
Cannot index array with "key"
Du hast .foo geschrieben, aber der aktuelle Wert ist ein Array. [] zum Iterieren anfügen:
# Falsch
echo '{"users":[{"name":"Alice"}]}' | jq '.users.name'
# Error: Cannot index array with "name"
# Richtig
echo '{"users":[{"name":"Alice"}]}' | jq '.users[].name'
# Ausgabe: "Alice"
Shell-Quoting-Ärger
Das gesamte jq-Programm in einfache Anführungszeichen setzen, innen Doppelquotes für String-Literale:
# Überall stabil
jq '.users[] | select(.role == "admin")'
# Bricht — Doppelquotes vom Shell zuerst interpretiert
jq ".users[] | select(.role == \"admin\")"
Windows-PowerShell-Randfälle
PowerShell behandelt einfache Anführungszeichen anders. Lieber doppelte Anführungszeichen um das Programm und innere Quotes escapen, oder ein Here-String:
jq "@'
.users[] | select(.role == \"admin\")
'@"
Für alles Nicht-Triviale den Filter in einer .jq-Datei speichern und jq -f filter.jq ausführen.
Fehlanwendung von -r
-r wirkt nur auf String-Ergebnisse. Bei einem Objekt kommt ein normales JSON-Objekt heraus:
echo '{"a":1}' | jq -r '.'
# Ausgabe: {"a":1} ← unverändert; -r hatte nichts zu entfernen
Soll ein konkretes Feld ohne Anführungszeichen kommen, erst selektieren: jq -r '.a'.
jq lehnt JSON mit Kommentaren oder abschließenden Kommas ab
echo '{"a": 1, /* Notiz */ "b": 2,}' | jq .
# parse error: Invalid numeric literal
jq folgt streng RFC 8259 JSON — keine Kommentare, keine abschließenden Kommas, keine Schlüssel ohne Anführungszeichen. Ist die Datei JSON5 oder JSONC (häufig bei Konfigurationsdateien), entferne diese Erweiterungen vor dem Pipen zu jq. Der JSON5- und JSONC-Formatierungsleitfaden erklärt, welche Parser sie unterstützen und wie man in striktes JSON konvertiert.
jq gegen Alternativen: gron, fx, jj, yq
jq ist nicht die einzige Option, und manchmal ist ein anderes Werkzeug schneller:
| Werkzeug | Stärke | Wann einsetzen |
|---|---|---|
| gron | Plättet JSON zu greppbaren Pfaden | Unbekannte Schemata erkunden — du weißt nicht, wo der Schlüssel ist |
| fx | Interaktiver TUI-Explorer mit Highlighting | Große JSON per Hand durchstöbern |
| jj | Deutlich schneller als jq, eingeschränkte Syntax | Heiße Schleifen mit Millionen Records |
| yq | Gleiche Filter-Sprache, aber für YAML | Kubernetes-Manifeste und CI-Konfiguration |
| Browser-JSON Formatter | Syntax-Highlight, präzise Fehlermeldungen, ohne Installation | Einzelne Antwort beim Entwickeln debuggen |
Im Shell-Alltag gewinnt jq bei Komponierbarkeit. Für spontane Exploration ist gron oft schneller. Für YAML yq — keine Versuche mit yq-dann-jq-Pipes.
Pro-Tipps für den Alltag
Ein paar Angewohnheiten, die jq natürlich wirken lassen:
-
Lege eine
.jqrcin$HOMEan. Hilfsfunktionen dort hinterlegen, und sie stehen bei jederjq-Ausführung zur Verfügung:def running: select(.status.phase == "Running"); def table(f): [f] | @tsv; -
Nutze jqplay.org für komplexe Filter. JSON links einfügen, Filter rechts iterieren, funktionierende Version ins Skript übernehmen.
-
Bau dir einen Cheat Sheet aus
history.history | grep 'jq ' | sort -u > ~/jq-patterns.txtfängt jedes tatsächlich benutzte Muster ein. -
Kombiniere mit dem Browser-JSON Formatter bei unbekannten Schemata. Erst visuell die Struktur erkunden, um den nötigen Pfad zu finden, dann das
jq-Kommando schreiben. -
Werte live beobachten:
watch -n 5 "curl -s api.example.com/health | jq '.uptime'"aktualisiert alle 5 Sekunden — ein kleines Ops-Dashboard ohne Abhängigkeiten.
FAQ
Was ist jq und warum nutzen Entwickler es?
jq ist ein Kommandozeilenprozessor für JSON. Er extrahiert, filtert und transformiert JSON in Shell-Pipelines ohne Python- oder Node-Skript — der kürzeste Weg von API-Antworten, Log-Dateien oder kubectl-Ausgaben zum gesuchten Feld.
Gibt es jq für Windows?
Ja. Installiere per winget install jqlang.jq, Chocolatey choco install jq oder lade das Binary von jqlang.org. Die Quoting-Regeln in PowerShell unterscheiden sich von bash — im Zweifel Filter in eine .jq-Datei speichern und jq -f filter.jq ausführen.
Wie unterscheidet sich jq von einem Browser-JSON-Formatter?
Ein JSON Formatter im Browser ist interaktiv — JSON einfügen, Highlighting und Fehler sehen, kopieren. jq ist nicht interaktiv — Transformation einmal als Filter beschreiben, in der Shell-Pipeline laufen lassen. Browser zum Debuggen einer Antwort; jq zum Automatisieren auf hunderten Eingaben.
Warum sagt jq „Cannot iterate over null”?
Du hast versucht (.[]), über einen null-Wert zu iterieren — meist, weil das Feld in der Eingabe fehlte. Beheben mit dem optionalen Operator .items[]? oder einem Default via .items // [] | .[].
Kann jq Dateien in-place verändern?
Nicht direkt — jq schreibt auf stdout. Temp-Datei verwenden oder sponge aus moreutils: jq '.version = "2.0"' config.json | sponge config.json. Immer zuerst das Original sichern; ein falsch geschriebener Filter überschreibt die Datei.
Wie nutze ich jq mit curl-Antworten?
curl -s in jq pipen. Das Flag -s schaltet den Fortschrittsbalken von curl stumm, sodass nur der JSON-Body bei jq ankommt:
curl -s https://api.github.com/users/octocat | jq '.name, .blog'
Was ist der Unterschied zwischen jq’s | und dem Shell-|?
Die Shell-Pipe transportiert Bytes zwischen Prozessen. Die jq-Pipe transportiert JSON-Werte zwischen Filtern innerhalb eines jq-Aufrufs. Ein Kommando mit vielen internen Pipes läuft in einem Prozess — günstiger als eine Kette aus jq | jq | jq.
Kann jq JSON Lines (NDJSON) verarbeiten?
Ja, nativ. jq liest jede Zeile als eigenständigen JSON-Wert, sofern sie durch Whitespace getrennt sind. -c gibt NDJSON aus, -s sammelt NDJSON in ein einziges Array.
Wie formatiere ich JSON ohne Filterung?
Den Identity-Filter nutzen: cat data.json | jq . oder jq . < data.json. Er parst, validiert und formatiert mit Zwei-Leerzeichen-Einrückung — ohne Filter.
Gibt es eine jq-Alternative mit grafischer Oberfläche?
Ja. fx bietet eine interaktive TUI. Für eine GUI ohne Installation deckt der Browser-JSON Formatter die meisten Explore-und-Validate-Bedürfnisse ab. Web-Tools wie jqplay.org bieten jq selbst mit Live-Vorschau.
Wann sollte ich jq statt eines Python-Skripts nutzen?
Greif zu jq, wenn die Aufgabe einmalig ist, in eine Shell-Pipeline passt und innerhalb von Filtern, Transformieren und Extrahieren bleibt. Wechsle zu Python, wenn du Unit-Tests, komplexen Zustand, Drittbibliotheken oder Verzweigungslogik brauchst, die eine .jq-Datei unleserlich machen würde.
Wie nutze ich reguläre Ausdrücke in jq?
jq bietet Regex über test("pattern"), match("pattern"), capture("pattern") und scan("pattern"), alle in PCRE-Syntax. Flags als zweites Argument: test("abc"; "i") für Groß-/Kleinschreibungs-Ignorierung. match liefert Offsets und Captures; scan emittiert jeden nicht überlappenden Treffer.
Wie behalte ich Umlaute (ä, ö, ü, ß) in der jq-Ausgabe?
jq gibt UTF-8 standardmäßig aus und erhält Umlaute, solange du kein -a / --ascii-output verwendest. Siehst du \u00e4 statt ä, liegt es meist am Terminal-Locale: prüfe, dass $LANG auf de_DE.UTF-8 oder en_US.UTF-8 gesetzt ist, und vermeide das -a-Flag.
Kernerkenntnisse
- Erst das Denkmodell: ein Filter rein, null oder mehr JSON-Werte raus, Komposition mit
|. Alles andere ist Syntax. - Nach Aufgabe lernen, nicht nach Operator: die 30 Muster decken rund 95 % des
jq-Alltags ab. - Null explizit behandeln:
?für stilles Überspringen,// defaultfür einen konkreten Fallback. Die meistenCannot iterate over null-Korrekturen sind eines von beiden. - Wissen, wann
jqdas falsche Werkzeug ist: einzelne Antworten gehören in einen Browser-JSON Formatter; YAML gehört zuyq; komplexe Logik gehört in echten Code. - Mit dem bestehenden Stack kombinieren:
jqglänzt innerhalb voncurl,kubectl,aws,dockerund Log-Pipelines. Als Kleber einsetzen, nicht als Logikschicht.
Für verwandte JSON-Workflows: der JSON5- und JSONC-Formatierungsleitfaden zu Syntaxerweiterungen für Konfigurationsdateien und der CSV-zu-JSON-Konvertierungsleitfaden zu Datenformat-Migrationen, bei denen jq in die Pipeline passt. Wenn dein JSON Zeitstempel enthält, deckt der Unix-Zeitstempel-Leitfaden die Fallstricke beim Transformieren von Datumsfeldern ab.