Reputation: 3675
I need to change the value of a set of keys (defined in a variable) in a JSON object using jq.
As example, I have this JSON object:
{
foo: {
bar: 1,
baz: 2,
qux: 3
}
}
and the following variable:
update_keys = ["bar", "baz"]
I would like to say 'change the value of the keys in update_keys to X'.
The following works:
.foo = (.foo |
to_entries |
map(if .key == "bar" or .key == "baz"
then . + { "value":"X" }
else .
end) |
from_entries)
But instead of if .key == "bar" or .key == "baz"
I am looking for a way to say if .key in update_keys
, or a similar logic.
Upvotes: 2
Views: 3361
Reputation: 14635
In this problem since $update_keys
is just an array all that is needed is
.foo[ $update_keys[] ] = "X"
e.g. if
["bar","baz"] as $update_keys
| .foo[ $update_keys[] ] = "X"
is in filter.jq
and data.json
contains the (slighty corrected) data
{
"foo": {
"bar": 1,
"baz": 2,
"qux": 3
}
}
then
jq -M -f filter.jq data.json
produces
{
"foo": {
"bar": "X",
"baz": "X",
"qux": 3
}
}
If you want to pass in the value for update keys instead of defining it in your script you can easily use --argjson
as peak's answer shows.
Upvotes: 0
Reputation: 116680
Here's a slightly different approach using --argjson
to parameterize update_keys, and index/1
:
$ cat update.jq
.foo |= with_entries( . as $in
| if $update_keys | index($in.key) then .value = "X" else empty end)
$ update_keys='["bar", "baz"]'
$ jq --argjson update_keys "$update_keys" -f update.jq input.json
Output:
{
"foo": {
"bar": "X",
"baz": "X"
}
}
Upvotes: 0
Reputation: 7656
Here you go.
Filter
.foo |= with_entries( .value = if ([.key] | inside(["bar", "baz"])) then "X" else .value end )
Input
{
"foo": {
"bar": 1,
"baz": 2,
"qux": 3
}
}
Output
{
"foo": {
"bar": "X",
"baz": "X",
"qux": 3
}
}
Check out the cookbook for more recipies and techniques of jq
usage:
https://github.com/stedolan/jq/wiki/Cookbook
Upvotes: 1