Home > Back-end >  jq - apply modifications from a file
jq - apply modifications from a file

Time:02-16

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.

  • Related