pb100
pb100

Reputation: 786

Compare json files but ignore values

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:

but

should not report that the following keys have different values:

I looked at the jq tool but I am not sure how to ignore values.

Upvotes: 3

Views: 760

Answers (1)

peak
peak

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

Related Questions