2015-04-21 16 views
9

Desidero aggiornare un valore in un dict, che posso solo identificare con un altro valore nel dict. Cioè, dato questo input:Aggiornare un valore in array di dict, utilizzando jq

[ 
    { 
    "format": "geojson", 
    "id": "foo" 
    }, 
    { 
    "format": "geojson", 
    "id": "bar" 
    }, 
    { 
    "format": "zip", 
    "id": "baz" 
    } 
] 

voglio cambiare baz 's che accompagna formato a 'CSV':

[ 
    { 
    "format": "geojson", 
    "id": "foo" 
    }, 
    { 
    "format": "geojson", 
    "id": "bar" 
    }, 
    { 
    "format": "csv", 
    "id": "baz" 
    } 
] 

ho trovato che questo funziona:

jq 'map(if .id=="baz" then .format="csv" else . end)' my.json 

Ma questo sembra piuttosto prolisso, quindi mi chiedo se c'è un modo più elegante per esprimere questo. jq sembra mancare un qualche tipo di selettore di espressioni, l'equivalente di potrebbe essere [@id='baz'] in xpath.

(Quando ho iniziato questa domanda, ho avuto [.[] |...], poi ho scoperto map, quindi non è così male come pensavo.)

risposta

11

Un'assegnazione complesso è quello che stai cercando:

jq '(.[] | select(.id == "baz") | .format) |= "csv"' my.json 

Forse non più corto ma è più elegante, come richiesto. Vedere l'ultima sezione dei documenti presso: http://stedolan.github.io/jq/manual/#Assignment

Edit: usando map:

jq 'map((select(.id == "baz") | .format) |= "csv")' my.json 
+0

Ah ah. Ho notato che c'è un tubo superfluo (credo). Quindi potrebbe essere: 'jq '(. [] | Select (.id ==" baz ") .format) | =" csv "' my.json' –

+0

Un'altra variante:' map (selezionare (.id == " corangamite "). format | =" csv ")' –

+0

sì, buono; Ho aggiunto una variante usando 'map'; Non sono sicuro della notazione con il tubo omesso –

Problemi correlati