Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Merge 2 JSON objects with jq

Tags:

json

merge

bash

key

jq

I have 2 json objects in 2 variables V1 and V2.

V1 is

{
  "Parameters: {
     "a": "value-of-a",
     "b": "value-of-b"
  }
}

V2 is

{
  "Parameters": {
     "a": "new-value-of-a",
     "c": "value-of-c"
  }
}

I want to override the V1's values with values from V2. I want to generate a new JSON that looks like this:

Expected

{
   "Parameters": {
      "a": "new-value-of-a",
      "b": "value-of-b"
   }
}

I tried the following:

(
echo '{ "Parameters": { "a": "value-of-a", "b": "value-of-b" } }'\
'{ "Parameters": { "a": "new-value-of-a", "c": "value-of-c" } }'\
| jq --slurp 'reduce .[] as $item ({}; . * $item)'
)

but this generates

Actual

{
   "Parameters": {
      "a": "new-value-of-a",
      "b": "value-of-b",
      "c": "value-of-c"
   }
}

The problem is that I don't want the nodes in V2 that don't exist in V1 to appear in the result. Can anyone help me?

like image 598
Johnny I Avatar asked Oct 15 '22 00:10

Johnny I


1 Answers

Here's a reduce-free solution that's conceptually simple and scales well:

jq -n '
   # Emit the object with key-value pairs of $o2 
   # for keys that appear in both . and $o2
   def commonKeys($o2):
     keys_unsorted as $k1
     | ($o2|keys_unsorted) as $k2
     | [($k1 - ($k1-$k2))[] | {(.): $o2[.]}] | add
   ;
   input.Parameters as $dict
   | input
   | .Parameters |= (. + commonKeys($dict))

' v2.json v1.json 
like image 100
peak Avatar answered Nov 09 '22 10:11

peak