Reputation: 786
I would like to compare two json files and report differencies but I am interested in keys only and not values. So for example the "json-diff" between the following two files (of course they are much more complicated):
{
"http": {
"https": true,
"swagger": {
"enabled": false
},
"scalingFactors": [0.1, 0.2]
}
}
{
"http": {
"https": true,
"swagger": {
"enabled": true
},
"scalingFactors": [0.1, 0.1],
"test": true
}
}
should report that there is missing key:
http.test
but
should not report that the following keys have different values:
http.swagger.enabled
http.scalingFactors
I looked at the jq
tool but I am not sure how to ignore values.
Upvotes: 3
Views: 760
Reputation: 116780
Ignoring potential complications having to do with arrays, looking at the "symmetric difference" of the sets of paths to scalars would make sense. As a starting point, you could thus consider:
jq -c '
[paths(scalars)] as $f1
| [input | paths(scalars)] as $f2
| ($f1 - $f2) + ($f2 - $f1)' file1.json file2.json
You might want to stringify the paths, but then again, it might be wise to avoid doing so if the mapping to the strings is not invertible.
If arrays are present, you might want to compare the paths while ignoring the array indices:
def p: [paths(scalars) | map(select(type=="string"))] | unique;
p as $f1
| (input | p) as $f2
| ($f1 - $f2) + ($f2 - $f1)
| .[]
The last line ensures that the result is a (possibly empty) stream, the point being that this makes it easy to check the return code to determine whether any difference was detected: simply use the -e command-line option. If there are no differences, the return code will then be 4.
One way to check if the stream is empty would be to use the -4
Upvotes: 2