Filtrera och välja JSON med jq-pipelines
Navigera i kapslade objekt och arrayer med jq-väljare, pipes och filtret select.
Filtrera och välja JSON med jq-pipelines är en gratis lektion i Bemästra Linux-kommandoraden och Bash-skriptning på CoddyKit. Detta är lektion 1 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för Bemästra Linux-kommandoraden och Bash-skriptning, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Bemästra Linux-kommandoraden och Bash-skriptning innehåller totalt 4 lektioner.
Vad är jq och varför ska det användas?
jq är ett lättviktigt och kraftfullt kommandoradsverktyg för att tolka, filtrera och omvandla JSON-data. Det är JSON-världens sed – Ni skickar JSON till verktyget via en pipe och får strukturerad utdata tillbaka.
- Är förinstallerat i de flesta Linux-distributioner eller kan installeras med
apt install jq/brew install jq - Fungerar sömlöst i skalets pipelines tillsammans med
curl,catoch andra verktyg - Stöder filtrering, mappning, reduktion och formatkonvertering
Det grundläggande anropet är: jq '<filter>' file.json eller via en pipe som cat file.json | jq '<filter>'. Filtret . (punkt) är identitetsfiltret – det skriver ut hela dokumentet i läsbart format.
# Pretty-print a JSON file
jq '.' data.json
# Or pipe from curl
curl -s https://api.github.com/users/torvalds | jq '.'Välj objektfält med punktnotation
För att komma åt ett fält i ett JSON-objekt använder Ni punktnotation: .fieldName. Ni kan kedja väljare för att navigera i nästlade objekt.
.name– fält på toppnivå.address.city– nästlat fält."field-with-dash"– fält med specialtecken måste omges av citattecken
Om fältet inte finns returnerar jq null i stället för att generera ett fel. Därför är det säkert att använda i skript utan extra null-kontroller för valfria fält.
# 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"Åtkomst till matriselement och iterering
JSON-arrayer nås med hakparentesnotation. jq använder nollbaserad indexering.
.items[0]– första elementet.items[-1]– sista elementet.items[1:3]– utsnitt (från index 1 till, men inte inklusive, 3).items[]– packa upp arrayen: skriver ut varje element som ett separat värde (detta är iteratorn)
Iteratorn [] är grundläggande i jq-pipelines – den låter Er tillämpa efterföljande filter på varje element oberoende av de andra.
# 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"Bygg jq-pipelines med pipe-operatorn
Precis som skalets pipe | har jq en egen intern pipe-operator. Den skickar utdata från ett filter som indata till nästa.
jq '.users[] | .name'– iterera över användare och hämta sedan namnet från var och enjq '.data | .items[] | .id'– navigera till data, packa upp items och hämta id
Pipes i ett jq-uttryck gör det möjligt att bygga komplexa omvandlingar steg för steg. Varje steg tar emot det föregående stegets resultat – inklusive flera värden från en iterator.
Viktig insikt: när en iterator producerar N värden körs varje efterföljande filter N gånger, en gång per värde.
# 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
# 25Filtrera med select()
Filtret select(condition) släpper endast igenom ett värde om villkoret är sant; annars producerar det ingen utdata. Det motsvarar grep eller WHERE i SQL i jq.
select(.age > 18)– behåll objekt där åldern är större än 18select(.status == "active")– jämförelse av likhetselect(.name | startswith("A"))– nästlat test av en sträng
Kombinera select med iteratorn för att filtrera arrayer: .items[] | select(.active) skriver endast ut element där .active är sanningsenligt.
# 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"Återskapa objekt och arrayer med {} och []
Med jq kan Ni omforma data genom att konstruera nya objekt med {} och nya arrayer med [].
{name: .name, city: .address.city}– välj och byt namn på fält i ett nytt objekt[.items[] | .id]– samla itererade värden i en ny array- Kortform:
{name, age}motsvarar{name: .name, age: .age}
Att omsluta en pipeline med [...] kallas arraykonstruktion och är nödvändigt när Ni vill ha en JSON-array som utdata i stället för en ström av värden.
# 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"]Arbeta med nästlade arrayer och rekursiv genomgång
JSON från verkliga system är ofta djupt nästlad. jq tillhandahåller två verktyg för djup navigering:
.a.b.c– explicit sökväg när strukturen är känd.. | .fieldName?– rekursiv genomgång: går igenom varje nod i trädet och skriver ut värden där nyckeln finns
Operatorn ? (try) undertrycker fel när ett fält inte finns vid en viss nod, vilket är avgörande när Ni använder rekursiv genomgång på heterogena träd.
Använd rekursiv genomgång sparsamt för stora dokument – varje nod besöks och det kan gå långsamt. Föredra explicita sökvägar när strukturen är förutsägbar.
# 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
# 2Praktiskt exempel: tolka API-svar från curl
Ett av de vanligaste användningsområdena för jq är att tolka svar från REST-API:er som hämtats med curl. Genom att kombinera curl -s (tyst läge) med en jq-pipeline får Ni ren dataextrahering som lämpar sig för skript.
- Extrahera ett enskilt värde:
curl -s URL | jq '.field' - Bygg en sammanfattningstabell: iterera över en array och återskapa objekt med endast de fält Ni behöver
- Använd
-r(rå utdata) för att ta bort de omgivande citattecknen från strängvärden – nödvändigt när värden tilldelas skalvariabler
Tips: lägg alltid till -r när jq-utdata ska användas som en skalvariabel eller skickas vidare till ett annat kommando.
#!/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"Använda map() och map_values()
jq tillhandahåller två praktiska högre ordningens funktioner för att omvandla samlingar:
map(f)– tillämpar filtretfpå varje element i en array och returnerar en ny array. Motsvarar[.[] | f].map_values(f)– tillämparfpå varje värde i ett objekt eller en array och bevarar nycklarna/indexen.
Dessa funktioner är mer lättlästa än att manuellt omsluta pipelines med [] och följer idiomatisk jq-stil för omvandlingar som ska förbli arrayer.
# 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}Hantera valfria fält och standardvärden med //
JSON-data från externa källor är ofta inkonsekvent – fält kan saknas eller vara null. jq tillhandahåller alternativoperatorn // (dubbelt snedstreck) för att ange ett standardvärde.
.nickname // "anonymous"– använd.nicknameom det inte är null/false, annars"anonymous".count // 0– numeriskt standardvärde- Kombinera med
select:select((.status // "inactive") == "active")
Detta är mycket mer koncist än motsvarigheten i skalet, ${VAR:-default}, och kan enkelt kombineras i längre pipelines.
# 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: 0Praktiskt skript: JSON-loggtolk
Strukturerad JSON-loggning är standard i moderna system. Här är ett realistiskt skript som läser en loggfil med JSON-objekt avgränsade med radbrytningar, filtrerar fram felposter och formaterar en lättläst sammanfattning.
Viktiga mönster:
-c(kompakt utdata) – ett JSON-objekt per rad, användbart när utdata skickas till skal-loopar--arg name value– injicera en skalvariabel som ett jq-strängargumentselectför filtrering efter loggnivå-rför rå strängutdata som passar 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 -rnKunskapskontroll: beteendet hos jq select()
Testa din förståelse av hur select() fungerar i en jq-pipeline.
Följande kommando används:
echo '[{"name":"Alice","age":30},{"name":"Bob","age":17},{"name":"Carol","age":22}]' | jq '[.[] | select(.age >= 18) | .name]'Vad blir resultatet?
Lektionssammanfattning: jq-pipelines för JSON-filtrering
Du har gått igenom de viktigaste jq-verktygen för att navigera i och filtrera JSON från kommandoraden:
- Punktnotation (
.field,.a.b.c) väljer fält från objekt - Åtkomst till arrayer (
.[0],.[]) indexerar och itererar över arrayer - Pipe-operatorn (
|) kopplar samman filter; varje steg bearbetar alla värden från föregående steg - select(cond) filtrerar värden och släpper endast igenom dem där villkoret är sant
- Konstruktion av objekt och arrayer (
{},[],map()) omformar data till nya strukturer - Alternativoperatorn (
//) anger standardvärden för null eller saknade fält - Flaggan -r tar bort citattecken vid tilldelning till skalvariabler; --arg infogar skalvariabler på ett säkert sätt
- Rekursiv sökning (
.. | .field?) söker i djupt nästlade träd när sökvägen är okänd
Med dessa byggstenar kan du omvandla alla JSON-svar från API:er, loggfiler eller konfigurationer till exakt den data dina skript behöver — utan att lämna terminalen.
Lär dig Bash med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 22
- Lektioner
- 88
Vanliga frågor
Är lektionen ”Filtrera och välja JSON med jq-pipelines” gratis?
Ja – hela texten till ”Filtrera och välja JSON med jq-pipelines” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i Bemästra Linux-kommandoraden och Bash-skriptning, kan Ni uppgradera till CoddyKit PRO. Kursen i Bemästra Linux-kommandoraden och Bash-skriptning innehåller totalt 4 lektioner.
Vad lär jag mig i ”Filtrera och välja JSON med jq-pipelines”?
Navigera i kapslade objekt och arrayer med jq-väljare, pipes och filtret select. Ni övar på Bemästra Linux-kommandoraden och Bash-skriptning med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig Bemästra Linux-kommandoraden och Bash-skriptning?
Du behöver inga förkunskaper. Utbildningen i Bemästra Linux-kommandoraden och Bash-skriptning på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 1 av 4.
Hur lång tid tar lektionen ”Filtrera och välja JSON med jq-pipelines”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här Bemästra Linux-kommandoraden och Bash-skriptning-lektionen?
Ja. Varje Bemästra Linux-kommandoraden och Bash-skriptning-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Filtrera och välja JSON med jq-pipelines
- Omforma och skapa JSON-objekt med jq
- Anropa REST-API:er med curl och jq tillsammans
- Redigera YAML-konfigurationsfiler med yq