I'm searching for a CLI (Windows) tool to compare 2 JSON files.

The trick is that the data objects within the JSON files may be in different orders (positions). Even if the order of data objects changes, if the objects themselves are unchanged, I want the tool to report that the files are equivalent.

I want to run the tool from a script, so it needs to run without interaction if the files are the same. I'm okay if it forces a UI when the files are not equivalent, but that's not preferred.

Because it will be running from a script, a hard requirement is that it returns an errorlevel environment variable that I can use to determine if the 2 JSON files are equivalent.

CLI is really what I prefer, but a GUI that conforms to the above will work too. So please don't hesitate to recommend either.

Related: Diff tool for JSON files?

  • Wait a minute, by "different positions" do you only mean dictionaries? Because in lists a different order may be quite intentional even though the items contained on either side may refer to the same set of items. Lists are ordered, after all. – 0xC0000022L Dec 29 '20 at 0:11

You can run both files through jq (available as a small Windows binary), let jq pretty-print and sort the data in both files according to your needs, and then perform an "ordinary" diff (with WinDiff, Meld, Diffuse).

the shell commands would be

 < file1.json jq  'keys' > file1.sorted.json
 < file2.json jq  'keys' > file2.sorted.json

diff file1.sorted.json file2.sorted.json

# or better

diff -q file1.sorted.json file2.sorted.json

#       -q, --brief
#              report only when files differ

# if output of diff -q is nonempty, files differ -> raise an error

If you know what's going on, continue with the unmodified files.

This obviously works only if the JSON objects differ only in their keys. This also assumes that the type info is preserved (e.g. the string representation of floats does not differ between the two files)

If the JSON objects differ in object values, or if the values contain nested objects (which themselves can differ in values or in subkey ordering), or if you want the order of the first-level-keys unchanged, but need to only compare the nested "value-objects" by some other criterion, you will need more complicated jq commands.
Check stackoverflow.com - some incredible jq experts there.

  • Thank knb. Your answer is helpful and similar to what I had thought about originally. I was concerned about the speed of running 3 executables to get 1 job done. Also, I am new to jq and I was concerned about the time required to uncover its power. All that said, based on someone smart (that's you) coming up with the same idea, I'm probably going to give it a try and run some quick performance metrics. Thanks! (P.S. I'm still hoping for 1 tool that can do the whole job!) – RockPaperLz- Mask it or Casket Dec 29 '20 at 16:34

Did you try and take a look at GNU Diffutils (diff)? Diff specifically has the "-B" or "--ignore-blank-lines" switch, which "Ignore changes whose lines are all blank" (see also a similar question on Stack Exchange).

There are other ways and variants as well to achieve the things you mentioned, such as using Vimdiff for example.

If you want to take a programmatic approach, you might want to take a look at the Levenshtein distance, which is a metric for measuring the difference between two Strings.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.