Transformering og bygging av JSON-objekter med jq
Endre datastrukturen med map, to_entries og objektkonstruksjon for å lage nye JSON-nyttelaster.
Transformering og bygging av JSON-objekter med jq er en gratis leksjon i DevOps-bootcamp på CoddyKit. Dette er leksjon 2 av 4. Du kan lese valgfritt 3 leksjoner fra denne læringsstien gratis i sin helhet – deretter låser CoddyKit PRO opp alle leksjoner, samt praktisk øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i DevOps-bootcamp, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i DevOps-bootcamp inneholder totalt 4 leksjoner.
Hvorfor omforme JSON?
Rå JSON fra API-er eller loggfiler har sjelden nøyaktig den strukturen De trenger. De kan motta et stort objekt, men bare ønske bestemte felt, eller måtte gi nøkler nye navn, flate ut nestede strukturer eller bygge en helt ny nyttelast som skal sendes til en annen tjeneste.
jq er en lett og kraftig JSON-behandler for kommandolinjen som gjør disse omformingene mulige i én enkelt pipeline. I denne leksjonen lærer De de tre viktigste teknikkene for å omforme data:
- Objektkonstruksjon – bygg et nytt JSON-objekt fra grunnen av
- map – bruk en omforming på hvert element i en array
- to_entries / from_entries – behandle et objekts nøkkel-verdi-par som en array, slik at De kan filtrere og bygge dem opp igjen
Alle eksemplene forutsetter at jq er installert (apt install jq / brew install jq).
Grunnleggende objektkonstruksjon
Den mest grunnleggende jq-funksjonen er objektkonstruksjon: å omslutte uttrykk med {} for å bygge et nytt JSON-objekt. De velger hvilke felt som skal tas med, og hva de skal kalles.
Syntaks:
{ newKey: .existingField }– gi et felt nytt navn{ name, age }– kortform når den nye nøkkelen har samme navn som feltet{ total: (.price * .qty) }– beregn en verdi direkte i uttrykket
Kodesnutten nedenfor leser et produkt-JSON og lager en mer kompakt struktur med det beregnede feltet subtotal.
#!/usr/bin/env bash
# Object construction: pick and rename fields
product='{
"id": 42,
"name": "Widget Pro",
"price": 9.99,
"qty": 3,
"warehouse": "EU-West"
}'
echo "$product" | jq '{
productId: .id,
name,
subtotal: (.price * .qty)
}'Bygge objekter fra nestede data
JSON fra virkeligheten er ofte nestet. jq lar Dem hente verdier fra nestede baner i en objektkonstruksjon og flate ut strukturen samtidig.
Bruk punktnotasjon for banen i verdiuttrykket i konstruksjonen:
{ city: .address.city }{ lat: .location.coords.lat }
Eksempelet nedenfor tar en dypt nestet brukerpost og lager et flatt sammendrag som egner seg for en CSV-overskriftsrad eller brødteksten i en API-forespørsel.
#!/usr/bin/env bash
user='{
"id": "u-001",
"profile": {
"displayName": "Ada Lovelace",
"contact": { "email": "ada@example.com", "phone": "+44-700" }
},
"plan": "pro"
}'
echo "$user" | jq '{
id,
name: .profile.displayName,
email: .profile.contact.email,
plan
}'Omforme arrayer med map
map(expr) tilsvarer for-each i jq: Det bruker expr på hvert element i en inndatarray og returnerer en ny array med samme lengde.
Viktige punkter:
map(expr)er kortform for[.[] | expr]- Uttrykket kan være et hvilket som helst jq-filter – også objektkonstruksjon
- Lenk sammen med
select()for å filtrere før omformingen
Kodesnutten behandler en liste over bestillinger og beholder bare feltene som trengs i et fraktdokument.
#!/usr/bin/env bash
orders='[
{"orderId": 1, "customer": "Alice", "total": 42.50, "status": "shipped"},
{"orderId": 2, "customer": "Bob", "total": 18.00, "status": "pending"},
{"orderId": 3, "customer": "Carol", "total": 99.99, "status": "shipped"}
]'
# Produce a shipping manifest: only shipped orders, slim fields
echo "$orders" | jq '[
.[] | select(.status == "shipped") | {
id: .orderId,
recipient: .customer,
amount: .total
}
]'map med beregnede felt
Inne i map kan De beregne nye verdier, konvertere typer og kombinere felt – ikke bare kopiere dem. Vanlige mønstre omfatter:
- Strenginterpolering:
"\(.first) \(.last)" - Aritmetikk:
(.price * 1.2 | round)for et påslag på 20 % - Betingelser:
if .score >= 90 then "A" else "B" end
Eksempelet nedenfor utvider en liste over ansatte ved å legge til et beregnet fullName og en seniority-etikett basert på antall års erfaring.
#!/usr/bin/env bash
staff='[
{"first": "Grace", "last": "Hopper", "years": 15},
{"first": "Alan", "last": "Turing", "years": 4},
{"first": "Linus", "last": "Torvalds","years": 9}
]'
echo "$staff" | jq 'map({
fullName: "\(.first) \(.last)",
years,
seniority: (if .years >= 10 then "senior" elif .years >= 5 then "mid" else "junior" end)
})'Forstå to_entries
to_entries konverterer et JSON-objekt til en array med par av typen {key, value}. Dette gjør array-operasjoner (map, select, sort) på feltene i et objekt mulig – noe De ikke kan gjøre direkte på et objekt.
Eksempel på omforming:
- Inndata:
{"a": 1, "b": 2} - Utdata:
[{"key": "a", "value": 1}, {"key": "b", "value": 2}]
Den omvendte operasjonen er from_entries, som gjør arrayen om til et objekt igjen. Sammen danner de idiomet to_entries | map(...) | from_entries for omforming på objektnivå.
#!/usr/bin/env bash
# Demonstrate to_entries and from_entries
config='{"host": "db.local", "port": 5432, "ssl": true}'
echo "--- to_entries output ---"
echo "$config" | jq 'to_entries'
echo "--- round-trip back to object ---"
echo "$config" | jq 'to_entries | from_entries'Filtrere nøkler med to_entries
En av de mest praktiske bruksområdene for to_entries er å filtrere dynamisk hvilke nøkler som skal beholdes eller fjernes basert på selve nøkkelnavnet – noe objektkonstruksjon ikke kan gjøre når De ikke kjenner nøkkelnavnene på forhånd.
Mønster:
to_entries | map(select(.key | test("regex"))) | from_entriesto_entries | map(select(.key != "secret")) | from_entries
Kodesnutten nedenfor fjerner alle nøkler som begynner med en understrek (interne/private felt) før et konfigurasjonsobjekt videresendes til en ekstern tjeneste.
#!/usr/bin/env bash
raw_config='{
"endpoint": "https://api.example.com",
"timeout": 30,
"_internalToken": "s3cr3t",
"_debugMode": true,
"retries": 3
}'
# Remove any key starting with underscore
echo "$raw_config" | jq '
to_entries
| map(select(.key | startswith("_") | not))
| from_entries
'Gi nøkler nye navn dynamisk med to_entries
Objektkonstruksjon gir nøkler nye navn når De kjenner navnene på forhånd. to_entries lar Dem gi nøkler nye navn programmatisk – for eksempel konvertere camelCase til snake_case eller legge til et prefiks.
Inne i map oppdaterer De feltet .key for hver oppføring og sender deretter resultatet gjennom from_entries:
map(.key |= gsub("(?<=[a-z])(?=[A-Z])"; "_") | .key |= ascii_downcase)– camelCase til snake_casemap(.key |= "app_" + .)– legg til et prefiks for hver nøkkel
Eksempelet setter prefikset APP_ foran alle miljøvariabelnavn for å navngi dem entydig før de settes inn i en container.
#!/usr/bin/env bash
env_vars='{"host": "localhost", "port": "8080", "debug": "false"}'
# Add APP_ prefix and uppercase all keys
echo "$env_vars" | jq '
to_entries
| map({ key: ("APP_" + (.key | ascii_upcase)), value })
| from_entries
'with_entries: den praktiske kortformen
Mønsteret to_entries | map(...) | from_entries er så vanlig at jq tilbyr en kortform: with_entries(expr).
Den er helt tilsvarende, men mer konsis:
with_entries(.value |= . * 2)– doble alle numeriske verdierwith_entries(select(.value != null))– fjern nøkler med null-verdiwith_entries(.key |= ascii_upcase)– bruk store bokstaver i alle nøkler
Kodesnutten fjerner alle nøkler med verdien null eller en tom streng – et vanlig oppryddingstrinn før en PATCH-forespørsel sendes til et REST-API.
#!/usr/bin/env bash
patch_body='{
"name": "Mehmet",
"email": "",
"phone": null,
"city": "Istanbul"
}'
# Drop empty/null fields before PATCH
cleaned=$(echo "$patch_body" | jq '
with_entries(select(.value != null and .value != ""))
')
echo "Cleaned payload:"
echo "$cleaned"
# In practice you would pipe to curl:
# curl -s -X PATCH https://api.example.com/users/1 \
# -H "Content-Type: application/json" \
# -d "$cleaned"Kombinere map og objektkonstruksjon i en pipeline
Reelle omforminger lenker sammen flere jq-operasjoner. En typisk pipeline for å klargjøre en API-nyttelast kan:
- Filtrere inndataarrayen med
map(select(...)) - Omforme hvert element med objektkonstruksjon
- Legge til beregnede felt
- Sortere resultatet
Eksempelet nedenfor leser en liste over servermålinger, beholder bare servere med høy CPU-bruk og lager en kompakt alarmnyttelast som er klar til å sendes med POST til en webhook.
#!/usr/bin/env bash
metrics='[
{"host": "web-01", "cpu": 23, "mem": 60, "region": "eu"},
{"host": "web-02", "cpu": 91, "mem": 88, "region": "eu"},
{"host": "db-01", "cpu": 78, "mem": 95, "region": "us"},
{"host": "db-02", "cpu": 12, "mem": 40, "region": "us"}
]'
alerts=$(echo "$metrics" | jq '[
.[] | select(.cpu > 75 or .mem > 85) | {
server: .host,
region,
severity: (if .cpu > 90 or .mem > 90 then "critical" else "warning" end),
metrics: { cpu: .cpu, mem: .mem }
}
] | sort_by(.severity)')
echo "$alerts"Bygge et nytt JSON-objekt fra flere kilder
jq kan slå sammen inndata og konstruere objekter som henter data fra flere JSON-kilder ved hjelp av addisjonsoperatoren + og variabelbinding med as $var.
Nyttige mønstre:
obj1 + obj2– slå sammen to objekter (verdien på høyre side vinner ved nøkkelkonflikter)--argjson– send et annet JSON-dokument inn som en variabel$ENV– les miljøvariabler direkte i jq
Kodesnutten slår sammen en grunnkonfigurasjon med miljøspesifikke overstyringer – et vanlig mønster for konfigurasjonsstyring av 12-faktor-applikasjoner i skallskript.
#!/usr/bin/env bash
base_config='{
"logLevel": "info",
"timeout": 30,
"retries": 3,
"database": "postgres://db.local/app"
}'
env_overrides='{
"logLevel": "debug",
"database": "postgres://db.staging/app_staging"
}'
# Merge: overrides win on conflicts
merged=$(echo "$base_config" | jq --argjson overrides "$env_overrides" '. + $overrides')
echo "Merged config:"
echo "$merged"Kunnskapssjekk: to_entries kontra map
De har følgende JSON-objekt og må fjerne alle nøkler der verdien er mindre enn 0, slik at De får et nytt objekt med bare ikke-negative verdier. Hvilket jq-uttrykk gjør dette riktig?
Inndata: {"a": 10, "b": -3, "c": 0, "d": 5}
Oppsummering av leksjonen: omforme JSON med jq
De har gått gjennom de viktigste teknikkene for å omforme JSON med jq:
- Objektkonstruksjon
{}– bygg nye objekter ved å velge, gi nye navn til og beregne felt fra inndata map(expr)– bruk en hvilken som helst omforming på hvert element i en array, inkludert nestet objektkonstruksjon ogselect()for filtreringto_entries/from_entries– konverter et objekt til en array med{key, value}-par, slik at De kan utføre array-operasjoner på nøkler og verdier, og konverter deretter tilbakewith_entries(expr)– den konsise kortformen for hele to_entries → map → from_entries-pipelinen- Slå sammen objekter med
+og--argjsonfor nyttelaster fra flere kilder
Disse byggeklossene kan kombineres: filtrer med select, omform med objektkonstruksjon, utvid med beregnede felt og lenk alt sammen i ett lesbart jq-uttrykk. Når De behersker disse mønstrene, kan De håndtere praktisk talt alle JSON-nyttelaster direkte i skallet uten å skrive et eget skript i Python eller Node.
Lær deg DevOps-bootcamp med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 142
- Leksjoner
- 568
Ofte stilte spørsmål
Er leksjonen «Transformering og bygging av JSON-objekter med jq» gratis?
Ja – du kan lese valgfritt 3 av leksjonene i læringsstien DevOps-bootcamp, inkludert «Transformering og bygging av JSON-objekter med jq», gratis i sin helhet her på nettet. Deretter låser CoddyKit PRO opp alle leksjoner, samt interaktiv øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Kurset i DevOps-bootcamp inneholder totalt 4 leksjoner.
Hva lærer jeg i «Transformering og bygging av JSON-objekter med jq»?
Endre datastrukturen med map, to_entries og objektkonstruksjon for å lage nye JSON-nyttelaster. Du øver på DevOps-bootcamp med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med DevOps-bootcamp?
Ingen tidligere erfaring er nødvendig. DevOps-bootcamp på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 2 av 4.
Hvor lang tid tar leksjonen «Transformering og bygging av JSON-objekter med jq»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne DevOps-bootcamp-leksjonen?
Ja. Alle DevOps-bootcamp-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- Filtrering og utvalg av JSON med jq-pipelines
- Transformering og bygging av JSON-objekter med jq
- Bruk av REST-API-er med curl og jq sammen
- Redigering av YAML-konfigurasjonsfiler med yq