JSON-objecten transformeren en opbouwen met jq
Hervorm gegevens met map, to_entries en objectconstructie om nieuwe JSON-payloads te genereren.
JSON-objecten transformeren en opbouwen met jq is een gratis DevOps-bootcamp-les op CoddyKit. Dit is les 2 van 4. Je kunt 3 lessen uit dit leerpad gratis volledig lezen — daarna ontgrendelt CoddyKit PRO alle lessen, plus praktische oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject DevOps-bootcamp. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus DevOps-bootcamp bevat in totaal 4 lessen.
Waarom JSON transformeren?
Ruwe JSON van API's of logbestanden heeft zelden precies de vorm die je nodig hebt. Je ontvangt misschien een groot object, maar wilt alleen specifieke velden, of je moet sleutels hernoemen, geneste structuren afvlakken of een volledig nieuwe payload opbouwen om naar een andere service te sturen.
jq is een lichtgewicht, krachtige JSON-verwerker voor de opdrachtregel die deze transformaties in één pijplijn mogelijk maakt. In deze les leer je de drie belangrijkste technieken om gegevens een andere vorm te geven:
- Objectconstructie — bouw een nieuw JSON-object vanaf nul
- map — pas een transformatie toe op elk element van een array
- to_entries / from_entries — behandel de sleutel-waardepaaren van een object als een array, zodat je ze kunt filteren en opnieuw opbouwen
Bij alle voorbeelden wordt ervan uitgegaan dat jq is geïnstalleerd (apt install jq / brew install jq).
Basisprincipes van objectconstructie
De meest fundamentele functie van jq is objectconstructie: plaats expressies tussen {} om een nieuw JSON-object op te bouwen. Je kiest welke velden je wilt opnemen en hoe je ze wilt noemen.
Syntax:
{ newKey: .existingField }— hernoem een veld{ name, age }— verkorte notatie wanneer de nieuwe sleutel dezelfde naam heeft als het veld{ total: (.price * .qty) }— bereken inline een waarde
Het onderstaande fragment leest JSON over een product en produceert een compactere structuur met een berekend veld 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)
}'Objecten construeren uit geneste gegevens
JSON uit de praktijk is vaak genest. Met jq kun je binnen een objectconstructor geneste paden benaderen en de structuur tegelijkertijd afvlakken.
Gebruik puntpadnotatie binnen de waarde-expressie van de constructor:
{ city: .address.city }{ lat: .location.coords.lat }
Het onderstaande voorbeeld neemt een diep genest gebruikersrecord en produceert een vlak overzicht dat geschikt is voor een CSV-koprij of de body van een API-verzoek.
#!/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
}'Arrays transformeren met map
map(expr) is het jq-equivalent van voor elk: het past expr toe op elk element van een invoerarray en retourneert een nieuwe array met dezelfde lengte.
Belangrijke punten:
map(expr)is een verkorte schrijfwijze voor[.[] | expr]- De expressie binnenin kan elk jq-filter zijn — ook objectconstructie
- Combineer dit met
select()om eerst te filteren en daarna te transformeren
Het fragment verwerkt een lijst met bestellingen en behoudt alleen de velden die nodig zijn voor een verzendmanifest.
#!/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 met berekende velden
Binnen map kun je nieuwe waarden berekenen, typen omzetten en velden combineren — je hoeft ze niet alleen te kopiëren. Veelgebruikte patronen zijn:
- Stringinterpolatie:
"\(.first) \(.last)" - Rekenkundige bewerking:
(.price * 1.2 | round)voor een opslag van 20% - Voorwaardelijke expressies:
if .score >= 90 then "A" else "B" end
Het onderstaande voorbeeld verrijkt een lijst met werknemers door een berekende fullName en een label seniority toe te voegen op basis van het aantal jaren ervaring.
#!/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)
})'to_entries begrijpen
to_entries zet een JSON-object om in een array met paren van {key, value}. Hierdoor kun je arraybewerkingen (map, select, sort) uitvoeren op de velden van een object — iets wat je niet rechtstreeks op een object kunt doen.
Voorbeeldtransformatie:
- Invoer:
{"a": 1, "b": 2} - Uitvoer:
[{"key": "a", "value": 1}, {"key": "b", "value": 2}]
De omgekeerde bewerking is from_entries, die de array weer omzet in een object. Samen vormen ze het idioom to_entries | map(...) | from_entries voor transformaties op objectniveau.
#!/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'Sleutels filteren met to_entries
Een van de praktischste toepassingen van to_entries is dynamisch bepalen welke sleutels je wilt behouden of verwijderen op basis van de naam van de sleutel zelf — iets wat objectconstructie niet kan wanneer je de sleutelnamen vooraf niet kent.
Patroon:
to_entries | map(select(.key | test("regex"))) | from_entriesto_entries | map(select(.key != "secret")) | from_entries
Het onderstaande fragment verwijdert alle sleutels die met een underscore beginnen (interne/private velden) voordat het een configuratieobject doorstuurt naar een externe service.
#!/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
'Sleutels dynamisch hernoemen met to_entries
Met objectconstructie hernoem je sleutels wanneer je hun namen tijdens het schrijven kent. Met to_entries kun je sleutels programmatisch hernoemen — bijvoorbeeld door camelCase om te zetten naar snake_case of door een voorvoegsel toe te voegen.
Werk binnen map het veld .key van elke entry bij en stuur het resultaat daarna door naar from_entries:
map(.key |= gsub("(?<=[a-z])(?=[A-Z])"; "_") | .key |= ascii_downcase)— camelCase naar snake_casemap(.key |= "app_" + .)— voeg aan elke sleutel een voorvoegsel toe
Het voorbeeld voegt aan alle namen van omgevingsvariabelen het voorvoegsel APP_ toe om ze vóór injectie in een container van een naamruimte te voorzien.
#!/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: de handige verkorte notatie
Het patroon to_entries | map(...) | from_entries komt zo vaak voor dat jq hiervoor een verkorte notatie biedt: with_entries(expr).
Deze is precies equivalent, maar beknopter:
with_entries(.value |= . * 2)— verdubbel elke numerieke waardewith_entries(select(.value != null))— verwijder sleutels met een null-waardewith_entries(.key |= ascii_upcase)— zet alle sleutels om naar hoofdletters
Het fragment verwijdert alle sleutels waarvan de waarde null of een lege tekenreeks is — een veelvoorkomende opschoonstap voordat je een PATCH-verzoek naar een REST-API stuurt.
#!/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"map en objectconstructie combineren in een pijplijn
Transformaties uit de praktijk koppelen meerdere jq-bewerkingen aan elkaar. Een typische pijplijn voor het voorbereiden van een API-payload kan het volgende doen:
- Filter de invoerarray met
map(select(...)) - Geef elk element een andere vorm met objectconstructie
- Voeg berekende velden toe
- Sorteer het resultaat
Het onderstaande voorbeeld leest een lijst met serverstatistieken, behoudt alleen servers met een hoog CPU-gebruik en produceert een compacte waarschuwingspayload die klaar is om met POST naar een webhook te worden gestuurd.
#!/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"Een nieuw JSON-object opbouwen uit meerdere bronnen
Met jq kun je invoer samenvoegen en objecten construeren die gegevens uit meerdere JSON-bronnen halen met de opteloperator + en variabelen binden met as $var.
Nuttige patronen:
obj1 + obj2— voeg twee objecten samen (bij conflicterende sleutels wint de rechterkant)--argjson— geef een tweede JSON-document door als variabele$ENV— lees omgevingsvariabelen rechtstreeks binnen jq
Het fragment voegt een basisconfiguratie samen met omgevingsspecifieke overschrijvingen — een veelgebruikt patroon voor het beheren van configuratie voor 12-factor-applicaties in shellscripts.
#!/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"Kenniscontrole: to_entries versus map
Je hebt het volgende JSON-object en moet alle sleutels verwijderen waarvan de waarde kleiner is dan 0, zodat een nieuw object met alleen niet-negatieve waarden ontstaat. Welke jq-expressie voert dit correct uit?
Invoer: {"a": 10, "b": -3, "c": 0, "d": 5}
Lesoverzicht: JSON transformeren met jq
Je hebt de essentiële technieken behandeld voor het een andere vorm geven van JSON met jq:
- Objectconstructie
{}— bouw nieuwe objecten door velden uit de invoer te selecteren, hernoemen en berekenen map(expr)— pas elke transformatie toe op elk element van een array, inclusief geneste objectconstructie enselect()voor filteringto_entries/from_entries— zet een object om in een array met paren van{key, value}, zodat je bewerkingen op sleutels en waarden kunt uitvoeren, en zet het daarna weer terugwith_entries(expr)— de beknopte verkorte notatie voor de volledige pijplijn to_entries → map → from_entries- Objecten samenvoegen met
+en--argjsonvoor payloads uit meerdere bronnen
Deze bouwstenen kun je combineren: filter met select, geef gegevens een andere vorm met objectconstructie, verrijk ze met berekende velden en koppel alles in één leesbare jq-expressie aan elkaar. Als je deze patronen beheerst, kun je vrijwel elke JSON-payload rechtstreeks in de shell bewerken zonder een apart script in Python of Node te schrijven.
Leer DevOps-bootcamp met een AI-tutor — gratis
Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.
- Cursussen
- 142
- Lessen
- 568
Veelgestelde vragen
Is de les “JSON-objecten transformeren en opbouwen met jq” gratis?
Ja — je kunt hier op het web alle 3 lessen van het leerpad DevOps-bootcamp, waaronder “JSON-objecten transformeren en opbouwen met jq”, gratis volledig lezen. Daarna ontgrendelt CoddyKit PRO alle lessen, plus interactieve oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. De cursus DevOps-bootcamp bevat in totaal 4 lessen.
Wat leer ik in “JSON-objecten transformeren en opbouwen met jq”?
Hervorm gegevens met map, to_entries en objectconstructie om nieuwe JSON-payloads te genereren. Je oefent met DevOps-bootcamp door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.
Heb ik ervaring nodig om met DevOps-bootcamp te beginnen?
Ervaring vooraf is niet nodig. DevOps-bootcamp op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 2 van 4.
Hoe lang duurt de les “JSON-objecten transformeren en opbouwen met jq”?
De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.
Kan ik code schrijven en uitvoeren in deze les over DevOps-bootcamp?
Ja. Elke les over DevOps-bootcamp bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.
Alle lessen in deze cursus
- JSON filteren en selecteren met jq-pipelines
- JSON-objecten transformeren en opbouwen met jq
- REST API's gebruiken met curl en jq samen
- YAML-configuratiebestanden bewerken met yq