When using this algorithm:
jq -s 'def deepmerge(a;b): reduce b[] as $item (a; reduce ($item | keys_unsorted[]) as $key (.; $item[$key] as $val | ($val | type) as $type | .[$key] = if ($type == "object") then deepmerge({}; [if .[$key] == null then {} else .[$key] end, $val]) elif ($type == "array") then (.[$key] + $val | unique) else $val end) ); deepmerge({}; .)' test1.json test2.json > merged-1.json nested arrays are not concatenated/merged, but copied sequentially. I assume this is because when the method stack created by the recursive algorithm unwinds, values are written in the order node >> root, and deeper nested child values are thus always overwritten by their higher parents.
Input files:
test1.json
{ "item1" : "test1", "item2" : "test2", "nestedItemsArray1" : [{ "nestedItem1Item1" : "nestItem1Item1", "nestedItem1Array1" : ["nestedItem1Array1Item1", "nestedItem1Array1Item2"] }, { "nestedItem1Item1" : "nestItem1Item2", "nestedItem1Array1" : ["nestedItem1Array1Item3", "nestedItem1Array1Item4"] }] } test2.json
{ "item1" : "test3", "item2" : "test4", "array1" : [ "array1item3", "array1item4" ], "nestedItemsArray1" : [{ "nestedItem1Item1" : "nestItem1Item1", "nestedItem1Array1" : ["nestedItem1Array1Item5", "nestedItem1Array1Item6"] }, { "nestedItem1Item1" : "nestItem1Item2", "nestedItem1Array1" : ["nestedItem1Array1Item7", "nestedItem1Array1Item8"] }] } Actual result:
{ "item1": "test3", "item2": "test4", "nestedItemsArray1": [ { "nestedItem1Item1": "nestItem1Item1", "nestedItem1Array1": [ "nestedItem1Array1Item1", "nestedItem1Array1Item2" ] }, { "nestedItem1Item1": "nestItem1Item2", "nestedItem1Array1": [ "nestedItem1Array1Item3", "nestedItem1Array1Item4" ] }, { "nestedItem1Item1": "nestItem1Item1", "nestedItem1Array1": [ "nestedItem1Array1Item5", "nestedItem1Array1Item6" ] }, { "nestedItem1Item1": "nestItem1Item2", "nestedItem1Array1": [ "nestedItem1Array1Item7", "nestedItem1Array1Item8" ] } ], "array1": [ "array1item3", "array1item4" ] } Expected result:
{ "item1": "test3", "item2": "test4", "nestedItemsArray1": [ { "nestedItem1Item1": "nestItem1Item1", "nestedItem1Array1": [ "nestedItem1Array1Item1", "nestedItem1Array1Item2", "nestedItem1Array1Item5", "nestedItem1Array1Item6" ] }, { "nestedItem1Item1": "nestItem1Item2", "nestedItem1Array1": [ "nestedItem1Array1Item3", "nestedItem1Array1Item4", "nestedItem1Array1Item7", "nestedItem1Array1Item8" ] } ], "array1": [ "array1item3", "array1item4" ] } Of course this is just one array deep, but I would like this to work on any number of nested levels, regardless of values being nested inside arrays or objects.