Trasformare e costruire oggetti JSON con jq
Rimodelli i dati con map, to_entries e la costruzione di oggetti per produrre nuovi payload JSON.
Trasformare e costruire oggetti JSON con jq è una lezione DevOps Bootcamp gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento DevOps Bootcamp, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso DevOps Bootcamp include 4 lezioni in totale.
Perché trasformare il JSON?
Il JSON grezzo proveniente dalle API o dai file di log raramente ha esattamente la struttura necessaria. Potrebbe ricevere un oggetto di grandi dimensioni ma aver bisogno solo di alcuni campi, oppure dover rinominare chiavi, appiattire strutture annidate o creare un payload completamente nuovo da inviare a un altro servizio.
jq è un potente processore JSON leggero da riga di comando, che rende possibili queste trasformazioni in un'unica pipeline. In questa lezione apprenderà le tre tecniche fondamentali per ristrutturare i dati:
- Costruzione di oggetti — crea un nuovo oggetto JSON da zero
- map — applica una trasformazione a ogni elemento di un array
- to_entries / from_entries — tratta le coppie chiave-valore di un oggetto come un array, così da poterle filtrare e ricostruire
Tutti gli esempi presuppongono che jq sia installato (apt install jq / brew install jq).
Nozioni di base sulla costruzione di oggetti
La funzionalità più fondamentale di jq è la costruzione di oggetti: racchiudere le espressioni tra {} per creare un nuovo oggetto JSON. Può scegliere quali campi includere e come denominarli.
Sintassi:
{ newKey: .existingField }— rinomina un campo{ name, age }— forma abbreviata quando la nuova chiave corrisponde al nome del campo{ total: (.price * .qty) }— calcola un valore direttamente nell'espressione
Il frammento seguente legge il JSON di un prodotto e genera una struttura più essenziale con un campo subtotal calcolato.
#!/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)
}'Costruire oggetti da dati annidati
Il JSON del mondo reale è spesso annidato. jq consente di accedere ai percorsi annidati all'interno di un costruttore di oggetti, appiattendo contemporaneamente la struttura.
Utilizzi la notazione con percorso puntato nell'espressione del valore del costruttore:
{ city: .address.city }{ lat: .location.coords.lat }
L'esempio seguente prende un record utente profondamente annidato e produce un riepilogo piatto, adatto a una riga di intestazione CSV o al corpo di una richiesta API.
#!/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
}'Trasformare gli array con map
map(expr) è l'equivalente jq di un for-each: applica expr a ogni elemento di un array in input e restituisce un nuovo array della stessa lunghezza.
Punti chiave:
map(expr)è una forma abbreviata di[.[] | expr]- L'espressione interna può essere qualsiasi filtro jq, inclusa la costruzione di oggetti
- Può essere concatenata con
select()per filtrare prima della trasformazione
Il frammento elabora un elenco di ordini, mantenendo solo i campi necessari per un documento di spedizione.
#!/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 con campi calcolati
All'interno di map può calcolare nuovi valori, convertire i tipi e combinare i campi, non solo copiarli. Alcuni schemi comuni sono:
- Interpolazione di stringhe:
"\(.first) \(.last)" - Aritmetica:
(.price * 1.2 | round)per un aumento del 20% - Condizionali:
if .score >= 90 then "A" else "B" end
L'esempio seguente arricchisce un elenco di dipendenti aggiungendo un fullName calcolato e un'etichetta seniority basata sugli anni di esperienza.
#!/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)
})'Capire to_entries
to_entries converte un oggetto JSON in un array di coppie {key, value}. In questo modo è possibile applicare operazioni sugli array (map, select, sort) ai campi di un oggetto, cosa che non è possibile fare direttamente su un oggetto.
Esempio di trasformazione:
- Input:
{"a": 1, "b": 2} - Output:
[{"key": "a", "value": 1}, {"key": "b", "value": 2}]
L'operazione inversa è from_entries, che riconverte l'array in un oggetto. Insieme formano l'idioma to_entries | map(...) | from_entries per le trasformazioni a livello di oggetto.
#!/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'Filtrare le chiavi con to_entries
Uno degli usi più pratici di to_entries consiste nel filtrare dinamicamente le chiavi da conservare o rimuovere in base al nome della chiave stessa, cosa che la costruzione di oggetti non consente quando i nomi delle chiavi non sono noti in anticipo.
Schema:
to_entries | map(select(.key | test("regex"))) | from_entriesto_entries | map(select(.key != "secret")) | from_entries
Il frammento seguente rimuove tutte le chiavi che iniziano con un carattere di sottolineatura (campi interni/privati) prima di inoltrare un oggetto di configurazione a un servizio esterno.
#!/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
'Rinominare dinamicamente le chiavi con to_entries
La costruzione di oggetti rinomina le chiavi quando i loro nomi sono noti al momento della scrittura. to_entries consente di rinominare le chiavi in modo programmatico, ad esempio convertendo camelCase in snake_case o aggiungendo un prefisso.
All'interno di map aggiorna il campo .key di ogni voce, quindi usa una pipe verso from_entries:
map(.key |= gsub("(?<=[a-z])(?=[A-Z])"; "_") | .key |= ascii_downcase)— da camelCase a snake_casemap(.key |= "app_" + .)— aggiunge un prefisso a ogni chiave
L'esempio aggiunge il prefisso APP_ a tutti i nomi delle variabili d'ambiente, così da creare uno spazio dei nomi prima di inserirle in un 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: la forma abbreviata più comoda
Lo schema to_entries | map(...) | from_entries è così comune che jq fornisce una forma abbreviata: with_entries(expr).
È esattamente equivalente, ma più conciso:
with_entries(.value |= . * 2)— raddoppia ogni valore numericowith_entries(select(.value != null))— rimuove le chiavi con valore nullwith_entries(.key |= ascii_upcase)— converte tutte le chiavi in maiuscolo
Il frammento rimuove tutte le chiavi il cui valore è null o una stringa vuota, un'operazione di pulizia comune prima di inviare una richiesta PATCH a un'API REST.
#!/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"Combinare map e la costruzione di oggetti in una pipeline
Le trasformazioni reali concatenano più operazioni jq. Una pipeline tipica per preparare un payload API potrebbe:
- Filtrare l'array in input con
map(select(...)) - Ristrutturare ogni elemento con la costruzione di oggetti
- Aggiungere campi calcolati
- Ordinare il risultato
L'esempio seguente legge un elenco di metriche dei server, mantiene solo i server con un utilizzo elevato della CPU e produce un payload compatto per gli avvisi, pronto per essere inviato con POST a un 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"Creare un nuovo oggetto JSON da più origini
jq può unire gli input e costruire oggetti che attingono a più origini JSON usando l'operatore di addizione + e il binding di variabili con as $var.
Schema utili:
obj1 + obj2— unisce due oggetti (in caso di conflitto tra chiavi prevale il valore a destra)--argjson— passa un secondo documento JSON come variabile$ENV— legge direttamente le variabili d'ambiente all'interno di jq
Il frammento unisce una configurazione di base con override specifici per l'ambiente, uno schema comune per gestire la configurazione di applicazioni secondo i principi 12-factor negli script shell.
#!/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"Verifica delle conoscenze: to_entries a confronto con map
Ha a disposizione il seguente oggetto JSON e deve rimuovere tutte le chiavi il cui valore è minore di 0, producendo un nuovo oggetto contenente solo valori non negativi. Quale espressione jq svolge correttamente questa operazione?
Input: {"a": 10, "b": -3, "c": 0, "d": 5}
Riepilogo della lezione: trasformare JSON con jq
Ha appreso le tecniche essenziali per ristrutturare JSON con jq:
- Costruzione di oggetti
{}— crea nuovi oggetti selezionando, rinominando e calcolando i campi dell'input map(expr)— applica qualsiasi trasformazione a ogni elemento di un array, inclusa la costruzione di oggetti annidati eselect()per il filtraggioto_entries/from_entries— converte un oggetto in un array di coppie{key, value}, consentendo operazioni sugli array con chiavi e valori, quindi lo riconvertewith_entries(expr)— la forma abbreviata della pipeline completa to_entries → map → from_entries- Unione di oggetti con
+e--argjsonper payload provenienti da più origini
Questi strumenti si combinano tra loro: filtri con select, ristruttura con la costruzione di oggetti, arricchisce con campi calcolati e concatena tutto in un'unica espressione jq leggibile. Padroneggiando questi schemi può gestire praticamente qualsiasi payload JSON direttamente nella shell, senza scrivere uno script dedicato in Python o Node.
Domande Frequenti
La lezione «Trasformare e costruire oggetti JSON con jq» è gratuita?
Sì — il testo completo di «Trasformare e costruire oggetti JSON con jq» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso DevOps Bootcamp, passa a CoddyKit PRO. Il corso DevOps Bootcamp include 4 lezioni in totale.
Cosa imparerò in «Trasformare e costruire oggetti JSON con jq»?
Rimodelli i dati con map, to_entries e la costruzione di oggetti per produrre nuovi payload JSON. Eserciti DevOps Bootcamp con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare DevOps Bootcamp?
Non è richiesta alcuna esperienza precedente. DevOps Bootcamp su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.
Quanto tempo richiede la lezione «Trasformare e costruire oggetti JSON con jq»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione DevOps Bootcamp?
Sì. Ogni lezione DevOps Bootcamp include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Filtrare e selezionare JSON con le pipeline jq
- Trasformare e costruire oggetti JSON con jq
- Usare insieme curl e jq per consumare API REST
- Modificare file di configurazione YAML con yq