jq Einzeiler Filtern und Transformieren von JSON aus der Befehlszeile ohne ein Skript zu schreiben
Sieben praktische jq-Rezepte für Backend-Entwickler und DevOps – mit select, map, to_entries, del, group_by und echten API-Verformungen. Eingabe und Ausgabe werden für jedes Muster angezeigt.
Sie sehen eine komprimierte API-Antwort in der Terminal. Sie müssen drei Felder extrahieren, die Null-Werte filtern und das Ergebnis an etwas anderes leiten. Ein Python-Skript dafür wäre 20 Zeilen lang und 2 Minuten, die Sie nicht haben. jq Behandelt das in einem Befehl – wenn Sie die Muster kennen.
Sieben Rezepte unten. Jedes davon behandelt ein Muster, das Sie häufig bei der Arbeit mit API-Antworten oder Protokolldateien treffen werden. Eingabe, Befehl und Ausgabe werden für jedes Rezept angegeben.
Installieren
brew install jq # macOS
apt-get install jq # Ubuntu/Debian
apk add jq # Alpine (Docker images)
Rezept 1: Ein Feld aus jedem Objekt in einem Array extrahieren
Das häufigste, was Sie mit jq: ein Feld aus jedem Element in einem JSON-Array extrahieren.
Eingabe (users.json)
[
{"id": 1, "name": "Alice", "email": "alice@example.com", "role": "admin"},
{"id": 2, "name": "Bob", "email": "bob@example.com", "role": "user"},
{"id": 3, "name": "Carol", "email": "carol@example.com", "role": "user"}
]
jq '.[].name' users.json
# → "Alice"
# "Bob"
# "Carol" (newline-separated stream)
.[] iteriert über jedes Element im Array; .name extrahiert das Feld. Das Ergebnis ist ein Strom – nützlich für die Leitung an andere Befehle. Wenn Sie ein gültiges JSON-Array benötigen:
jq 'map(.name)' users.json
# → ["Alice", "Bob", "Carol"]
map(.name) ist eine Abkürzung für [.[] | .name] — wendet den Ausdruck auf jedes Element an und umschließt die Ergebnisse in ein Array. Sie werden map() viel verwenden.
Rezept 2: Filtern mit select
Behalten Sie nur die Objekte, die eine Bedingung erfüllen; entfernen Sie die übrigen.
jq 'map(select(.role == "admin"))' users.json
[
{"id": 1, "name": "Alice", "email": "alice@example.com", "role": "admin"}
]
select(expr) leitet das Element nur dann durch, wenn der Ausdruck wahr ist – alles andere verschwindet. Wenn es in map() gehalten wird, bleibt das Ergebnis als Array. Weitere Beispiele:
# Numeric comparison
jq 'map(select(.score > 80))' results.json
# Not-null check
jq 'map(select(.error != null))' events.json
# String contains (requires test)
jq 'map(select(.message | test("timeout")))' logs.json
Rezept 3: Objekte mit map
Wählen Sie nur die Felder aus, die Sie benötigen, und benennen Sie sie ggf. in derselben Passage um.
jq 'map({name: .name, role: .role})' users.json
[
{"name": "Alice", "role": "admin"},
{"name": "Bob", "role": "user"},
{"name": "Carol", "role": "user"}
]
Sie erstellen ein neues Objekt für jedes Element. Um einen Schlüssel umzubenennen, ändern Sie die linke Seite des Kolons:
jq 'map({username: .name, access_level: .role})' users.json
Eine Abkürzung, die Tasten einspart: {name} ist äquivalent zu {name: .name}. Wenn Sie ein Feld unverändert lassen möchten, müssen Sie den Schlüssel nicht zweimal schreiben:
jq 'map({id, name, role})' users.json
Rezept 4: Schlüssel umbenennen mit to_entries und from_entries
map ist gut, wenn Sie wissen, welche Schlüssel existieren. Wenn Sie die Schlüssel selbst transformieren müssen – beispielsweise eine Präfix hinzufügen, Namenskonventionen ändern oder Schlüssel basierend auf einer Auflistung umbenennen – to_entries ist das richtige Muster.
Eingabe (config.json)
{"api_url": "https://api.example.com", "timeout": 30, "retry_count": 3}
# Add cfg_ prefix to every key
jq 'to_entries | map(.key = "cfg_" + .key) | from_entries' config.json
{"cfg_api_url": "https://api.example.com", "cfg_timeout": 30, "cfg_retry_count": 3}
to_entries verändert {"k": "v"} hinein [{"key": "k", "value": "v"}]. Nachdem Sie die Einträge in dem resultierenden Array verändert haben, from_entries rekonstruiert das Objekt. Um einen bestimmten Schlüssel ohne die anderen zu umbenennen:
jq 'to_entries | map(if .key == "api_url" then .key = "endpoint" else . end) | from_entries' config.json
Rezept 5: Felder entfernen mit del
Das Gegenteil von Reshaping: behalten Sie alles und entfernen Sie einige spezifische Felder. Der Hauptfall ist die Entfernung sensibler Daten vor dem Protokollieren oder vor dem Übergeben eines Payloads an einen Dritten.
jq 'map(del(.email))' users.json
[
{"id": 1, "name": "Alice", "role": "admin"},
{"id": 2, "name": "Bob", "role": "user"},
{"id": 3, "name": "Carol", "role": "user"}
]
Löschen Sie mehrere Felder auf einmal oder verschachtelte Pfade:
# Multiple top-level fields at once
jq 'del(.password, .token, .refresh_token)' user.json
# Nested path
jq 'del(.user.internal_id)' response.json
# All fields named "debug" at any depth (recursive descent)
jq 'del(.. | .debug? // empty)' response.json
Rezept 6: Filtern, Reshaping und Sortieren in einem Durchgang
Die echte Leistung liegt in der Kette dieser Grundelemente. Hier ist ein Muster, das sich häufig bei der Arbeit mit paginierten API-Antworten zeigt: Einsteigen in ein verschachteltes Array, es filtern, die Objekte umformen und das Ergebnis sortieren.
Eingabe (repos.json)
{
"total_count": 3,
"items": [
{"id": 1, "name": "repo-alpha", "stargazers_count": 142, "language": "Go", "private": false},
{"id": 2, "name": "repo-beta", "stargazers_count": 89, "language": "Python", "private": true},
{"id": 3, "name": "repo-gamma", "stargazers_count": 310, "language": "Go", "private": false}
]
}
jq '.items
| map(select(.private == false and .language == "Go"))
| sort_by(-.stargazers_count)
| map({name, stars: .stargazers_count})' repos.json
[
{"name": "repo-gamma", "stars": 310},
{"name": "repo-alpha", "stars": 142}
]
Der Pipeline:
.items— Einsteigen in das verschachtelte Arraymap(select(...))— Filtern in einem Durchgang;andkettet Bedingungensort_by(-.stargazers_count)— negiert den Wert für eine absteigende Sortierung;sort_by(.field)allein gibt aufsteigendmap({name, stars: .stargazers_count})— endgültige Umformung;{name}ist eine Abkürzung für{name: .name}
Rezept 7: Anzahl der Log-Niveaus mit group_by
Frequenzanalyse an strukturierten Log-Ausgaben – ohne Datenbank, ohne awk-Übungen.
Eingabe (logs.json)
[
{"level": "error", "msg": "connection timeout", "service": "auth"},
{"level": "info", "msg": "request received", "service": "api"},
{"level": "error", "msg": "null pointer exception", "service": "worker"},
{"level": "warn", "msg": "slow query detected", "service": "db"},
{"level": "error", "msg": "rate limit exceeded", "service": "api"}
]
jq 'group_by(.level) | map({level: .[0].level, count: length}) | sort_by(-.count)' logs.json
[
{"level": "error", "count": 3},
{"level": "info", "count": 1},
{"level": "warn", "count": 1}
]
group_by(.level) gibt ein Array von Arrays zurück – jedes Unteralles enthält alle Einträge, die denselben Wert haben. .[0].level zieht den Namen des Levels aus dem ersten Element der Gruppe; length zählt, wie viele Einträge in der Gruppe vorhanden sind.
Fügen Sie eine pro-Dienst-Aufteilung in derselben Abfrage hinzu:
jq 'group_by(.level) | map({
level: .[0].level,
count: length,
services: map(.service) | unique
})' logs.json
Schnellübersicht
Die oben genannten Muster in tabellarischer Form, falls Sie eine schnelle Erinnerung benötigen:
| Was Sie wollen | jq-Ausdruck |
|---|---|
| Alle Werte eines Feldes | map(.field) |
| Filtern von passenden Einträgen | map(select(.field == "val")) |
| Jedes Objekt umformen | map({newKey: .oldKey}) |
| Alle Schlüssel umbenennen | to_entries | map(.key = ...) | from_entries |
| Felder entfernen | map(del(.field1, .field2)) |
| Aufsteigend sortieren | sort_by(.field) |
| Absteigend sortieren | sort_by(-.field) |
| Gruppen zählen | group_by(.field) | map({key: .[0].field, count: length}) |
| Alle Schlüssel eines Objekts erhalten | keys |
| Anzahl der Elemente in einem Array | length |
| Einzigartige Werte eines Feldes | map(.field) | unique |
Vor dem Start: Das Blob beherrschen
API-Antworten kommen oft komprimiert oder tief verschachtelt zurück. Wenn Sie nicht sicher sind, welchen Pfad Sie benötigen, fügen Sie den JSON-Text in die JSON-Formatierer — es formatiert schön mit zusammenfaltbaren Knoten, sodass Sie den Pfad vor dem Schreiben des jq Ausdrucks erkennen können. Nachdem ein Transformationsschritt durchgeführt wurde, ist das JSON-Vergleich Tool nützlich, um die Vor- und Nachbearbeitung zu überprüfen, wenn Sie Objekte umformen oder Felder entfernen und sicherstellen möchten, dass nichts unerwartetes verändert wurde.
Diese sieben Muster decken den Großteil der JSON-Verarbeitung ab, die Sie am Befehlszeileninterface durchführen werden. Die echte Kraft liegt in der Kette – sobald Sie Filtern, Umformen und Sortieren können, können Sie die meisten API-Antworten ohne ein Skript verarbeiten.
Das könnte Ihnen auch gefallen
Erweiterungen installieren
IO-Tools zu Ihrem Lieblingsbrowser hinzufügen für sofortigen Zugriff und schnellere Suche
恵 Die Anzeigetafel ist eingetroffen!
Anzeigetafel ist eine unterhaltsame Möglichkeit, Ihre Spiele zu verfolgen. Alle Daten werden in Ihrem Browser gespeichert. Weitere Funktionen folgen in Kürze!
Unverzichtbare Tools
Alle Neuheiten
AlleAktualisieren: Unser neuestes Werkzeug was added on Juni 26, 2026
