Reputation:
I'm trying to modify nested JSON objects using the jq <map>
function in a bash/shell script; something similar to this blog entry but attempting to adapt the examples here to nested objects.
The returned JSON to be modified as follows:
{
"name": "vendor-module",
"dependencies": {
"abc": {
"from": "[email protected]",
"resolved": "https://some.special.url",
"version": "2.4.0"
},
"acme": {
"from": "[email protected]",
"resolved": "<CHANGE_THIS>",
"version": "1.2.3"
}
}
}
This would be my attempt:
modules="`node -pe 'JSON.parse(process.argv[1]).dependencies.$dependency' \
"$(cat $wrapped)"`"
version="1.2.3"
resolved="some_url"
cat OLD.json |
jq 'to_entries |
map(if .dependencies[0].$module[0].from == "$module@$version"
then . + {"resolved"}={"$resolved"}
else .
end
) |
from_entries' > NEW.json
Obviously this doesn't work. When I run the script the NEW.json
is created but without modifications or returned errors. If I don't target a nested object (e.g., "name": "vendor-module"
), The script works as expected. I am sure there is a way to do it using native bash and jq..?? Any help (with the proper escaping) will be greatly appreciated.
UPDATE:
Thnx from the help of Charles Duffy's answer, and his suggestion of using sponge
, The solution that works well for me is:
jq --arg mod "acme" --arg resolved "Some URL" \
'.dependencies[$mod].resolved |= $resolved' \
OLD.json | sponge OLD.json
Upvotes: 0
Views: 3204
Reputation: 134811
If you know the name of the dependency you want to update, you could just index into it.
$ jq --arg dep "$dep" --arg resolved "$resolved" \
'.dependencies[$dep].resolved = $resolved' \
OLD.json > NEW.json
Otherwise, to modify a dependency based on the name (or other property), search for the dependency and update.
$ jq --arg version "$version" --arg resolved "$resolved" \
'(.dependencies[] | select(.version == $version)).resolved = $resolved' \
OLD.json > NEW.json
Upvotes: 2
Reputation: 295278
For your existing sample data, the following suffices:
jq --arg mod "acme" \
--arg resolved "some_url" \
'.dependencies[$mod].resolved=$resolved' \
<in.json >out.json
...to filter on the from
, by contrast:
jq --arg new_url "http://new.url/" \
--arg target "[email protected]" \
'.dependencies=(.dependencies
| to_entries
| map(if(.value.from == $target)
then .value.resolved=$new_url
else . end)
| from_entries)' \
<in.json >out.json
Upvotes: 0