How to merge 2 JSON objects from 2 files using jq?
Since 1.4 this is now possible with the *
operator. When given two objects, it will merge them recursively. For example,
jq -s '.[0] * .[1]' file1 file2
Important: Note the -s (--slurp)
flag, which puts files in the same array.
Would get you:
{ "value1": 200, "timestamp": 1382461861, "value": { "aaa": { "value1": "v1", "value2": "v2", "value3": "v3", "value4": 4 }, "bbb": { "value1": "v1", "value2": "v2", "value3": "v3" }, "ccc": { "value1": "v1", "value2": "v2" }, "ddd": { "value3": "v3", "value4": 4 } }, "status": 200}
If you also want to get rid of the other keys (like your expected result), one way to do it is this:
jq -s '.[0] * .[1] | {value: .value}' file1 file2
Or the presumably somewhat more efficient (because it doesn't merge any other values):
jq -s '.[0].value * .[1].value | {value: .}' file1 file2
Use jq -s add
:
$ echo '{"a":"foo","b":"bar"} {"c":"baz","a":0}' | jq -s add{ "a": 0, "b": "bar", "c": "baz"}
This reads all JSON texts from stdin into an array (jq -s
does that) then it "reduces" them.
(add
is defined as def add: reduce .[] as $x (null; . + $x);
, which iterates over the input array's/object's values and adds them. Object addition == merge.)
Who knows if you still need it, but here is the solution.
Once you get to the --slurp
option, it's easy!
--slurp/-s: Instead of running the filter for each JSON object in the input, read the entire input stream into a large array and run the filter just once.
Then the +
operator will do what you want:
jq -s '.[0] + .[1]' config.json config-user.json
(Note: if you want to merge inner objects instead of just overwriting the left file ones with the right file ones, you will need to do it manually)