We can merge two objects recursively with *
operator. For example like this: jq '.[0] * .[1]' -s a.json b.json
. The only problem (I realized) with it is it doesn't merge the arrays. But some guys did it.
What I want is the opposite. Assuming the things in b.json are always exist in a.json; a.json, b.json and the result respectively:
{
"background": {
"service_worker": "js/background.js",
"type": "module"
},
"manifest_version": 3,
"permissions": [
"storage",
"unlimitedStorage"
]
}
{
"background": {
"type": "module"
},
"permissions": [
"unlimitedStorage"
]
}
{
"background": {
"service_worker": "js/background.js"
},
"manifest_version": 3,
"permissions": [
"storage"
]
}
There are some questions on Stack Overflow like this but they are specific cases. I rather have a generic one like the meld
function.
I tried to edit the meld
function but couldn't achieve anything worth to mention.
Using the following definitions, $a | subtract_json($b)
produces the desired result, where $a and $b represent the values in a.json and b.json respectively:
def relevant_paths:
paths
| select( .[-1] | type != "number") ;
def is_scalar: type | IN("object", "array") | not;
def subtract_json($y):
. as $x
| reduce ($y | relevant_paths) as $p ( $x;
if (getpath($p)|type == "array") and
($y|getpath($p)|type == "array")
then setpath($p; getpath($p) - ($y|getpath($p)) )
elif (getpath($p)|is_scalar) and
($y|getpath($p)|is_scalar)
then delpaths( [$p] )
end);