Using jq, I am trying to update the value of each object in an array, the new value calculated from the value of other keys in the same array, and returning the whole updated JSON.
Test data saved in "cardata.json":
{
"data": {
"cars": [
{
"type": "limo",
"rating": null,
"comfort": 1,
"specs": {
"seats": 6,
"heat": true,
"color": "black"
}
},
{
"type": "sedan",
"rating": null,
"comfort": 2,
"specs": {
"seats": 4,
"heat": true,
"color": "blue"
}
},
{
"type": "open",
"rating": null,
"comfort": 3,
"specs": {
"seats": 2,
"heat": true,
"color": "red"
}
},
{
"type": "sport",
"rating": null,
"comfort": 5,
"specs": {
"seats": 1,
"heat": false,
"color": "yellow"
}
}
]
}
}
So this command
jq '( .data.cars | map(.rating = (if .specs.seats > 3 then "OK" else "Too small" end)) )' cardata.json
does the right thing, sort of, but only returns the updated cars object
[
{
"type": "limo",
"rating": "OK",
"comfort": 1,
"specs": {
"seats": 6,
"heat": true,
"color": "black"
}
},
{
"type": "sedan",
"rating": "OK",
"comfort": 2,
"specs": {
"seats": 4,
"heat": true,
"color": "blue"
}
},
{
"type": "open",
"rating": "Too small",
"comfort": 3,
"specs": {
"seats": 2,
"heat": true,
"color": "red"
}
},
{
"type": "sport",
"rating": "Too small",
"comfort": 5,
"specs": {
"seats": 1,
"heat": false,
"color": "yellow"
}
}
]
but I cannot get the whole JSON.
What do I do wrong?
You were very close. To update an object in-place, you can use |=
:
jq '
.data.cars |= map(
.rating =
if .specs.seats > 3 then
"OK"
else
"Too small"
end
)
' cardata.json
See jq playground.
Alternatively, using the array iterator .[]
instead of map
(h/t ikegami):
jq '
.data.cars[] |= (
.rating =
if .specs.seats > 3 then
"OK"
else
"Too small"
end
)
' cardata.json