JSON mit jq-Pipelines filtern und auswählen
Navigieren Sie mit jq-Selektoren, Pipes und dem select-Filter durch verschachtelte Objekte und Arrays.
JSON mit jq-Pipelines filtern und auswählen ist eine kostenlose DevOps Bootcamp-Lektion auf CoddyKit. Dies ist Lektion 1 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des DevOps Bootcamp-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der DevOps Bootcamp-Kurs umfasst insgesamt 4 Lektionen.
Was ist jq und warum sollten Sie es verwenden?
jq ist ein schlankes, leistungsfähiges Befehlszeilenwerkzeug zum Parsen, Filtern und Transformieren von JSON-Daten. Es ist das sed für JSON: Sie leiten JSON hinein und erhalten strukturierte Ausgabe zurück.
- Auf den meisten Linux-Distributionen vorinstalliert oder über
apt install jq/brew install jqverfügbar - Funktioniert nahtlos in Shell-Pipelines mit
curl,catund anderen Werkzeugen - Unterstützt Filtern, Abbilden, Reduktion und Formatkonvertierung
Der grundlegende Aufruf lautet: jq '<filter>' file.json oder als Pipeline cat file.json | jq '<filter>'. Der Filter . (Punkt) ist die Identitätsfunktion – er gibt das gesamte Dokument formatiert aus.
# Pretty-print a JSON file
jq '.' data.json
# Or pipe from curl
curl -s https://api.github.com/users/torvalds | jq '.'Objektfelder mit Punktnotation auswählen
Um auf ein Feld in einem JSON-Objekt zuzugreifen, verwenden Sie die Punktnotation: .fieldName. Verschachtelte Objekte können Sie über mehrere Selektoren hintereinander durchlaufen.
.name– Feld der obersten Ebene.address.city– verschachteltes Feld."field-with-dash"– Felder mit Sonderzeichen benötigen Anführungszeichen
Wenn das Feld nicht vorhanden ist, gibt jq null zurück, statt einen Fehler zu erzeugen. Dadurch können Sie es in Skripten sicher verwenden, ohne optionale Felder zusätzlich auf null prüfen zu müssen.
# Given: {"name":"Alice","address":{"city":"Berlin","zip":"10115"}}
echo '{"name":"Alice","address":{"city":"Berlin","zip":"10115"}}' | jq '.name'
# Output: "Alice"
echo '{"name":"Alice","address":{"city":"Berlin","zip":"10115"}}' | jq '.address.city'
# Output: "Berlin"Auf Array-Elemente zugreifen und iterieren
Auf JSON-Arrays greifen Sie mit der Klammernotation zu. jq verwendet eine nullbasierte Indizierung.
.items[0]– erstes Element.items[-1]– letztes Element.items[1:3]– Ausschnitt (Index 1 bis, aber nicht einschließlich, 3).items[]– das Array aufspalten: gibt jedes Element als separaten Wert aus (dies ist der Iterator)
Der Iterator [] ist grundlegend für jq-Pipelines: Mit ihm können Sie nachfolgende Filter unabhängig auf jedes Element anwenden.
# Given an array of users
echo '[{"name":"Alice"},{"name":"Bob"},{"name":"Carol"}]' | jq '.[0]'
# Output: {"name":"Alice"}
# Iterate all elements and extract .name from each
echo '[{"name":"Alice"},{"name":"Bob"},{"name":"Carol"}]' | jq '.[].name'
# Output:
# "Alice"
# "Bob"
# "Carol"jq-Pipelines mit dem Pipe-Operator erstellen
Wie die Shell-Pipe | verfügt auch jq über einen eigenen internen Pipe-Operator. Er übergibt die Ausgabe eines Filters als Eingabe an den nächsten.
jq '.users[] | .name'– Benutzer durchlaufen und anschließend aus jedem den Namen extrahierenjq '.data | .items[] | .id'– zu den Daten navigieren, die Elemente aufspalten und die IDs extrahieren
Pipes innerhalb eines jq-Ausdrucks ermöglichen es, komplexe Transformationen Schritt für Schritt aufzubauen. Jede Stufe erhält alles, was die vorherige Stufe erzeugt hat – einschließlich mehrerer Werte aus einem Iterator.
Wichtige Erkenntnis: Wenn ein Iterator N Werte erzeugt, wird jeder nachgelagerte Filter N-mal ausgeführt, einmal pro Wert.
# Nested pipeline: navigate -> iterate -> extract
echo '{"users":[{"name":"Alice","age":30},{"name":"Bob","age":25}]}' \
| jq '.users[] | .name'
# Output:
# "Alice"
# "Bob"
# Chain more stages
echo '{"users":[{"name":"Alice","age":30},{"name":"Bob","age":25}]}' \
| jq '.users[] | .age'
# Output:
# 30
# 25Mit select() filtern
Der Filter select(condition) lässt einen Wert nur dann passieren, wenn die Bedingung wahr ist; andernfalls erzeugt er keine Ausgabe. Er entspricht in jq dem grep-Befehl oder WHERE in SQL.
select(.age > 18)– Objekte behalten, deren Alter größer als 18 istselect(.status == "active")– Gleichheitsprüfungselect(.name | startswith("A"))– verschachtelte Zeichenkettenprüfung
Kombinieren Sie select mit dem Iterator, um Arrays zu filtern: .items[] | select(.active) gibt nur Elemente aus, bei denen .active einen Wahrheitswert ergibt.
# Filter array elements by a condition
echo '[{"name":"Alice","age":30},{"name":"Bob","age":17},{"name":"Carol","age":25}]' \
| jq '.[] | select(.age >= 18) | .name'
# Output:
# "Alice"
# "Carol"
# Filter by string equality
echo '[{"name":"Alice","role":"admin"},{"name":"Bob","role":"user"}]' \
| jq '.[] | select(.role == "admin") | .name'
# Output: "Alice"Objekte und Arrays mit {} und [] neu aufbauen
Mit jq können Sie Daten umformen, indem Sie neue Objekte mit {} und neue Arrays mit [] erstellen.
{name: .name, city: .address.city}– Felder auswählen und in ein neues Objekt übernehmen[.items[] | .id]– iterierte Werte wieder in einem Array sammeln- Kurzform:
{name, age}entspricht{name: .name, age: .age}
Das Einschließen einer Pipeline in [...] wird als Array-Erstellung bezeichnet und ist unerlässlich, wenn Sie als Ausgabe ein JSON-Array statt eines Wertestroms benötigen.
# Reshape: keep only selected fields
echo '[{"id":1,"name":"Alice","password":"secret"},{"id":2,"name":"Bob","password":"secret"}]' \
| jq '[.[] | {id, name}]'
# Output:
# [
# {"id": 1, "name": "Alice"},
# {"id": 2, "name": "Bob"}
# ]
# Collect filtered names into an array
echo '[{"name":"Alice","active":true},{"name":"Bob","active":false}]' \
| jq '[.[] | select(.active) | .name]'
# Output: ["Alice"]Mit verschachtelten Arrays und rekursivem Abstieg arbeiten
JSON aus der Praxis ist häufig tief verschachtelt. jq stellt zwei Werkzeuge für die Navigation in die Tiefe bereit:
.a.b.c– expliziter Pfad, wenn die Struktur bekannt ist.. | .fieldName?– rekursiver Abstieg: durchläuft jeden Knoten im Baum und gibt Werte aus, wenn der Schlüssel vorhanden ist
Der ?-Operator (try) unterdrückt Fehler, wenn ein Feld an einem bestimmten Knoten nicht vorhanden ist. Das ist entscheidend, wenn Sie den rekursiven Abstieg auf heterogene Bäume anwenden.
Verwenden Sie den rekursiven Abstieg bei großen Dokumenten sparsam – er besucht jeden Knoten und kann langsam sein. Bevorzugen Sie explizite Pfade, wenn die Struktur vorhersehbar ist.
# Explicit deep path
echo '{"a":{"b":{"c":42}}}' | jq '.a.b.c'
# Output: 42
# Recursive descent: find all "id" values anywhere in the tree
echo '{"users":[{"id":1,"profile":{"id":99}},{"id":2}]}' \
| jq '.. | .id?'
# Output:
# 1
# 99
# 2Praxisbeispiel: curl-API-Antworten parsen
Einer der häufigsten Anwendungsfälle für jq ist das Parsen von REST-API-Antworten, die mit curl abgerufen wurden. Die Kombination aus curl -s (stille Ausgabe) und einer jq-Pipeline ermöglicht eine übersichtliche, skriptfähige Datenextraktion.
- Einen einzelnen Wert extrahieren:
curl -s URL | jq '.field' - Eine Übersichtstabelle erstellen: ein Array durchlaufen und Objekte mit nur den benötigten Feldern neu aufbauen
-r(rohe Ausgabe) verwenden, um die umschließenden Anführungszeichen von Zeichenkettenwerten zu entfernen – unerlässlich bei der Zuweisung an Shell-Variablen
Tipp: Fügen Sie immer -r hinzu, wenn die jq-Ausgabe als Shell-Variable verwendet oder an einen anderen Befehl weitergeleitet wird.
#!/usr/bin/env bash
# Fetch GitHub repo info and extract specific fields
REPO="torvalds/linux"
RESPONSE=$(curl -s "https://api.github.com/repos/${REPO}")
# Extract fields
STARS=$(echo "$RESPONSE" | jq -r '.stargazers_count')
LANG=$(echo "$RESPONSE" | jq -r '.language')
DESC=$(echo "$RESPONSE" | jq -r '.description')
echo "Stars : $STARS"
echo "Lang : $LANG"
echo "Desc : $DESC"map() und map_values() verwenden
jq stellt zwei praktische Funktionen höherer Ordnung zum Transformieren von Sammlungen bereit:
map(f)– wendet den Filterfauf jedes Element eines Arrays an und gibt ein neues Array zurück. Entspricht[.[] | f].map_values(f)– wendetfauf jeden Wert eines Objekts oder Arrays an und behält die Schlüssel bzw. Indizes bei.
Diese Funktionen sind besser lesbar, als Pipelines manuell in [] einzuschließen, und entsprechen dem idiomatischen jq-Stil für Transformationen, die als Arrays erhalten bleiben sollen.
# map: extract a field from each element
echo '[{"name":"Alice","score":95},{"name":"Bob","score":80}]' \
| jq 'map(.name)'
# Output: ["Alice", "Bob"]
# map with select: filter + transform in one step
echo '[{"name":"Alice","score":95},{"name":"Bob","score":60}]' \
| jq 'map(select(.score >= 70) | .name)'
# Output: ["Alice"]
# map_values: multiply every value in an object by 2
echo '{"a":1,"b":2,"c":3}' | jq 'map_values(. * 2)'
# Output: {"a":2,"b":4,"c":6}Optionale Felder und Standardwerte mit // behandeln
JSON-Daten aus externen Quellen sind häufig uneinheitlich – Felder können fehlen oder null sein. jq stellt den Alternativoperator // (doppelter Schrägstrich) bereit, um einen Standardwert anzugeben.
.nickname // "anonymous"–.nicknameverwenden, wenn der Wert nicht null oder false ist, andernfalls"anonymous".count // 0– numerischer Standardwert- Mit
selectkombinieren:select((.status // "inactive") == "active")
Das ist deutlich kompakter als das entsprechende Shell-Konstrukt ${VAR:-default} und lässt sich problemlos in längeren Pipelines verwenden.
# Provide defaults for missing/null fields
echo '[{"name":"Alice","role":"admin"},{"name":"Bob"}]' \
| jq '[.[] | {name, role: (.role // "user")}]'
# Output:
# [
# {"name": "Alice", "role": "admin"},
# {"name": "Bob", "role": "user"}
# ]
# Numeric default
echo '{"items":[1,2,3]}' | jq '.total // 0'
# Output: 0Praxis-Skript: JSON-Log-Parser
Strukturiertes JSON-Logging ist in modernen Systemen Standard. Hier ist ein praxisnahes Skript, das eine JSON-Logdatei mit einem JSON-Objekt pro Zeile einliest, Fehlereinträge filtert und eine lesbare Zusammenfassung formatiert.
Wichtige verwendete Muster:
-c(kompakte Ausgabe) – ein JSON-Objekt pro Zeile, praktisch für die Weiterleitung an Shell-Schleifen--arg name value– eine Shell-Variable als jq-Zeichenkettenargument übergebenselectzum Filtern nach Log-Level-rfür die Ausgabe roher Zeichenketten, geeignet fürecho
#!/usr/bin/env bash
# Parse newline-delimited JSON logs and report ERRORs
# Each log line: {"level":"ERROR","msg":"...","ts":"2024-01-15T10:23:00Z","svc":"auth"}
LOG_FILE="/var/log/app/app.log"
LEVEL="ERROR"
echo "=== $LEVEL entries in $LOG_FILE ==="
jq -r --arg lvl "$LEVEL" \
'select(.level == $lvl) | "[\(.ts)] [\(.svc)] \(.msg)"' \
"$LOG_FILE"
# Count errors per service
echo ""
echo "=== Error count by service ==="
jq -r --arg lvl "$LEVEL" \
'select(.level == $lvl) | .svc' "$LOG_FILE" \
| sort | uniq -c | sort -rnWissenscheck: Verhalten von jq select()
Testen Sie Ihr Verständnis dafür, wie select() innerhalb einer jq-Pipeline funktioniert.
Gegeben ist der folgende Befehl:
echo '[{"name":"Alice","age":30},{"name":"Bob","age":17},{"name":"Carol","age":22}]' | jq '[.[] | select(.age >= 18) | .name]'Wie lautet die Ausgabe?
Lektionszusammenfassung: jq-Pipelines zum Filtern von JSON
Sie haben die grundlegenden jq-Werkzeuge zum Navigieren und Filtern von JSON über die Kommandozeile behandelt:
- Punktnotation (
.field,.a.b.c) wählt Felder aus Objekten aus - Array-Zugriff (
.[0],.[]) greift per Index auf Arrays zu und durchläuft sie - Pipe-Operator (
|) verkettet Filter; jede Stufe verarbeitet alle Werte der vorherigen Stufe - select(cond) filtert Werte und gibt nur diejenigen weiter, für die die Bedingung wahr ist
- Erstellung von Objekten und Arrays (
{},[],map()) formt Daten in neue Strukturen um - Alternativoperator (
//) liefert Standardwerte für null oder fehlende Felder - -r-Flag entfernt Anführungszeichen für die Zuweisung an Shell-Variablen; --arg fügt Shell-Variablen sicher ein
- Rekursiver Abstieg (
.. | .field?) durchsucht tief verschachtelte Strukturen, wenn der Pfad unbekannt ist
Mit diesen Bausteinen können Sie jede JSON-API-Antwort, Protokolldatei oder Konfiguration genau in die Daten umwandeln, die Ihre Skripte benötigen – und das alles, ohne das Terminal zu verlassen.
Häufig gestellte Fragen
Ist die Lektion „JSON mit jq-Pipelines filtern und auswählen“ kostenlos?
Ja — der vollständige Text von „JSON mit jq-Pipelines filtern und auswählen“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des DevOps Bootcamp-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der DevOps Bootcamp-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „JSON mit jq-Pipelines filtern und auswählen“?
Navigieren Sie mit jq-Selektoren, Pipes und dem select-Filter durch verschachtelte Objekte und Arrays. Du übst DevOps Bootcamp mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um DevOps Bootcamp zu starten?
Keine Vorkenntnisse erforderlich. DevOps Bootcamp auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 1 von 4.
Wie lange dauert die Lektion „JSON mit jq-Pipelines filtern und auswählen“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser DevOps Bootcamp-Lektion Code schreiben und ausführen?
Ja. Jede DevOps Bootcamp-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- JSON mit jq-Pipelines filtern und auswählen
- JSON-Objekte mit jq umformen und erstellen
- REST-APIs gemeinsam mit curl und jq nutzen
- YAML-Konfigurationsdateien mit yq bearbeiten