I have some json content in a file: content.json
{
"Type": {
"OS": "Windows"
},
"Network": {
"Protocol": "unknown",
"Port": 80
}
}
And some json updates in a file: updates.json
{
"Network": {
"Protocol": "HTTP"
}
}
How can I use jq to read updates.json and apply its content to content.json?
CAVEAT: I cannot predict the what's in updates.json. The jq script must be smart enough to just apply whatever it finds.
The output should be:
{
"Type": {
"OS": "Windows"
},
"Network": {
"Protocol": "HTTP",
"Port": 80
}
}
This script does almost what I want:
jq 'add' -s content.json updates.json
The results are:
{
"Type": {
"OS": "Windows"
},
"Network": {
"Protocol": "HTTP"
}
}
But as you can see, the "Port" entry is deleted.
CodePudding user response:
Perhaps the "recursive addition" operator *
will meet your needs:
< contents.json jq --argfile updates updates.json '
. * $updates
'
CodePudding user response:
The following illustrates one approach you could take:
< content.json jq --argfile updates updates.json '
.Network = $updates.Network
'
Or, depending on your precise requirements, you might like to consider:
< content.json jq --argfile updates updates.json '
.Network |= with_entries(select(.value != "unknown"))
| .Network = $updates.Network
'
CodePudding user response:
If you want the occurrences of "unknown" to determine the updates:
< content.json jq --argfile updates updates.json '
reduce paths(. == "unknown") as $p (.;
setpath($p; $updates | getpath($p)) )
'
CodePudding user response:
A more generic method:
jq -s 'def multiply:reduce .[] as $i ({}; . * $i);
multiply' content.json updates.json
So you can put multiple files.