Reputation: 863
This should be easy enough... I want to rename a few keys (ideally with jq), whatever I do seems to error though. Here is a json example below:
[
{
"fruit": "strawberry",
"veg": "apple",
"worker": "gardener"
}
]
I'd like to rename the veg key to fruit2 (or example, whatever is easiest) and also the worker key to job.
I realize this is possible in sed, but I'm trying to get to grips with jq
Upvotes: 52
Views: 34190
Reputation: 639
jq '[.[] | { fruit2: .veg, other_key: .other_orig_key }]'
check this example
Upvotes: 1
Reputation: 20380
Here's how to use if-then-else-end
with elif
to rename multiple keys:
map(with_entries(.key |=
if . == "fruit" then "fruit2"
elif . == "worker" then "job"
else . end))
(jqplay example)
Note in the current development branch / upcoming 1.7 release the empty else
branch will be optional and could be removed, but it's still required in v1.6.
Upvotes: 2
Reputation: 116670
The key (:-) is with_entries. E.g., given a single object:
with_entries(if .key == "veg" then .key = "fruit2" else . end)
In your case, since you have an array of objects, you could wrap the above in map( ... )
.
Note that if the original JSON object already has a key named "fruit2", then the usual "last-most wins" rule applies, where in this case, "last-most" refers to the array of key-value pairs that is used to determine the final result (as per the def of with_entries
).
Upvotes: 34
Reputation: 1102
For anyone looking to manipulate the key
with a value from value
:
$ echo '{ "foo": {"id": 123}, "bar": {"id":456} }' | jq 'to_entries | map({key:(.key + "-" +(.value.id|tostring)), value:.value}) | from_entries'
If there is a shorter way to do it (maybe using with_entries
), I would be happy to know.
Upvotes: 0
Reputation: 92854
Use the following jq approach:
jq '[.[] | .["fruit2"] = .veg | .["job"] = .worker | del(.veg, .worker)]' file
The output:
[
{
"fruit": "strawberry",
"fruit2": "apple",
"job": "gardener"
}
]
Upvotes: 53