If your shell supports process substitution (Bash-style follows, see docs):
diff <(jq --sort-keys . A.json) <(jq --sort-keys . B.json)
Objects key order will be ignored, but array order will still matter. It is possible to work-around that, if desired, by sorting array values in some other way, or making them set-like (e.g. ["foo", "bar"] → {"foo": null, "bar": null}; this will also remove duplicates).
Alternatively, substitute diff for some other comparator, e.g. cmp, colordiff, or vimdiff, depending on your needs. If all you want is a yes or no answer, consider using cmp and passing --compact-output to jq to not format the output for a potential small performance increase.
If your shell supports process substitution (Bash-style follows, see docs):
diff <(jq --sort-keys . A.json) <(jq --sort-keys . B.json)
Objects key order will be ignored, but array order will still matter. It is possible to work-around that, if desired, by sorting array values in some other way, or making them set-like (e.g. ["foo", "bar"] → {"foo": null, "bar": null}; this will also remove duplicates).
Alternatively, substitute diff for some other comparator, e.g. cmp, colordiff, or vimdiff, depending on your needs. If all you want is a yes or no answer, consider using cmp and passing --compact-output to jq to not format the output for a potential small performance increase.
Use jd with the -set option:
No output means no difference.
$ jd -set A.json B.json
Differences are shown as an @ path and + or -.
$ jd -set A.json C.json
@ ["People",{}]
+ "Carla"
The output diffs can also be used as patch files with the -p option.
$ jd -set -o patch A.json C.json; jd -set -p patch B.json
{"City":"Boston","People":["John","Carla","Bryan"],"State":"MA"}
https://github.com/josephburnett/jd#command-line-usage
Faster and simpler with the command line: deep-comparing JSON files with jq
Compare json files
command line - CLI tool to compare 2 JSON files without regards to order of data objects AND returns an errorlevel environment variable - Software Recommendations Stack Exchange
Feature: Add a "diff" built-in function/filter/operator
Say I have 2 json files.
#1
{
"ID": 1,
"Value": "A"
}
{
"ID": 2,
"Value": "B",
}
#2
{
"ID": 2,
"Value": "B"
},
{
"ID": 1,
"Value": "A",
}
I would like a compare that says these 2 files are the same.
Just because they are not in the same order they are not different.
Are there any tools that will tell me they are the same?
thanks
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.
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.
Check out this python library jsondiff , that will help you to identify the diff's
import json
import jsondiff
json1 = json.loads(
'{"isDynamic": false, "name": "", "value": "SID:<sid>", "description": "instance","argsOrder": 1,"isMultiSelect": false}')
json2 = json.loads(
'{ "name": "", "value": "SID:<sid>","isDynamic": false, "description": "instance","argsOrder": 1,"isMultiSelect": false}')
res = jsondiff.diff(json1, json2)
if res:
print("Diff found")
else:
print("Same")
UPDATED: See https://eggachecat.github.io/jycm-json-diff-viewer/ for a live demo! Now it has a JS-native implementation.
Affiliation: I am the author of this lib.
Yes! You can diff it with jycm which has a rendering tool out of the box.
It uses LCS, Edit distance and Kuhn–Munkres to diff arrays.
Here's an universal example with set in set and value changes in some set
from jycm.helper import make_ignore_order_func
from jycm.jycm import YouchamaJsonDiffer
left = {
"set_in_set": [
{
"id": 1,
"label": "label:1",
"set": [
1,
5,
3
]
},
{
"id": 2,
"label": "label:2",
"set": [
4,
5,
6
]
}
]
}
right = {
"set_in_set": [
{
"id": 2,
"label": "label:2",
"set": [
6,
5,
4
]
},
{
"id": 1,
"label": "label:1111",
"set": [
3,
2,
1
]
}
]
}
ycm = YouchamaJsonDiffer(left, right, ignore_order_func=make_ignore_order_func([
"^set_in_set$",
"^set_in_set->\\[\\d+\\]->set$"
]))
ycm.diff()
expected = {
'list:add': [
{'left': '__NON_EXIST__', 'right': 2, 'left_path': '', 'right_path': 'set_in_set->[1]->set->[1]'}
],
'list:remove': [
{'left': 5, 'right': '__NON_EXIST__', 'left_path': 'set_in_set->[0]->set->[1]', 'right_path': ''}
],
'value_changes': [
{'left': 'label:1', 'right': 'label:1111', 'left_path': 'set_in_set->[0]->label',
'right_path': 'set_in_set->[1]->label', 'old': 'label:1', 'new': 'label:1111'}
]
}
assert ycm.to_dict(no_pairs=True) == expected
you can set no_pairs=False to get the all pairs. Here's a rendered example:

As for the example here, you can use it as:
from jycm.helper import make_ignore_order_func
from jycm.jycm import YouchamaJsonDiffer
left = {
"data": [{"x": 1, "y": 2}, {"x": 3, "y": 4}]
}
right = {
"data": [{"x": 3, "y": 4}, {"x": 1, "y": 2}]
}
ycm = YouchamaJsonDiffer(left, right, ignore_order_func=make_ignore_order_func([
"^data",
]))
ycm.diff()
assert ycm.to_dict(no_pairs=True) == {}
Bonus, you the values are interrupted as coordinates on plain, you can even define a operator to determine whether two points should be matched!(Then comparing their values)
Here's the code:
from typing import Tuple
from jycm.helper import make_ignore_order_func
from jycm.jycm import YouchamaJsonDiffer
from jycm.operator import BaseOperator
import math
left = {
"data": [
{"x": 1, "y": 1},
{"x": 10, "y": 10},
{"x": 100, "y": 100}
]
}
right = {
"data": [
{"x": 150, "y": 150},
{"x": 10, "y": 11},
{"x": 2, "y": 3}
]
}
class L2DistanceOperator(BaseOperator):
__operator_name__ = "operator:l2distance"
__event__ = "operator:l2distance"
def __init__(self, path_regex, distance_threshold):
super().__init__(path_regex=path_regex)
self.distance_threshold = distance_threshold
def diff(self, level: 'TreeLevel', instance, drill: bool) -> Tuple[bool, float]:
distance = math.sqrt(
(level.left["x"] - level.right["x"]) ** 2 + (level.left["y"] - level.right["y"]) ** 2
)
info = {
"distance": distance,
"distance_threshold": self.distance_threshold,
"pass": distance < self.distance_threshold
}
if not drill:
instance.report(self.__event__, level, info)
return False, 1 if info["pass"] else 0
return True, 1 if info["pass"] else 0
ycm = YouchamaJsonDiffer(left, right, ignore_order_func=make_ignore_order_func([
"^data$",
]), custom_operators=[
L2DistanceOperator("^data->\\[.*\\]$", 10),
])
ycm.diff()
expected = {
'just4vis:pairs': [
{'left': 1, 'right': 2, 'left_path': 'data->[0]->x', 'right_path': 'data->[2]->x'},
{'left': {'x': 1, 'y': 1}, 'right': {'x': 2, 'y': 3}, 'left_path': 'data->[0]',
'right_path': 'data->[2]'},
{'left': 1, 'right': 3, 'left_path': 'data->[0]->y', 'right_path': 'data->[2]->y'},
{'left': {'x': 1, 'y': 1}, 'right': {'x': 2, 'y': 3}, 'left_path': 'data->[0]',
'right_path': 'data->[2]'},
{'left': {'x': 1, 'y': 1}, 'right': {'x': 2, 'y': 3}, 'left_path': 'data->[0]',
'right_path': 'data->[2]'}
],
'list:add': [
{'left': '__NON_EXIST__', 'right': {'x': 150, 'y': 150}, 'left_path': '', 'right_path': 'data->[0]'}
],
'list:remove': [
{'left': {'x': 100, 'y': 100}, 'right': '__NON_EXIST__', 'left_path': 'data->[2]', 'right_path': ''}
],
'operator:l2distance': [
{'left': {'x': 1, 'y': 1}, 'right': {'x': 2, 'y': 3}, 'left_path': 'data->[0]',
'right_path': 'data->[2]', 'distance': 2.23606797749979, 'distance_threshold': 10,
'pass': True},
{'left': {'x': 10, 'y': 10}, 'right': {'x': 10, 'y': 11}, 'left_path': 'data->[1]',
'right_path': 'data->[1]', 'distance': 1.0, 'distance_threshold': 10,
'pass': True}
],
'value_changes': [
{'left': 1, 'right': 2, 'left_path': 'data->[0]->x', 'right_path': 'data->[2]->x', 'old': 1, 'new': 2},
{'left': 1, 'right': 3, 'left_path': 'data->[0]->y', 'right_path': 'data->[2]->y', 'old': 1, 'new': 3},
{'left': 10, 'right': 11, 'left_path': 'data->[1]->y', 'right_path': 'data->[1]->y', 'old': 10, 'new': 11}
]
}
assert ycm.to_dict() == expected
As you can see jycm report addition and remove for points {'x': 150, 'y': 150} and {'x': 100, 'y': 100} for their
distances are too far (more than 10) and value-change for the other two points.
P.S. RENDERER DEMO

Hi all,
I posted on this yesterday but didn't end up getting anywhere. I thought I'd post again with some other ideas and see how I go.
Scenario:
I've got two JSON files pulled from the same website, which I'm importing a day apart using json.dump with indent=4.
I would like to compare the old JSON file with the new JSON file with the possibility that the newer file will have additional objects.
The only problem is, it needs to be readable as a JSON so I can print/use the values.
The only solution that has come close so far is to try and format the file first, then use subprocess and bash to run:
def bash_command(cmd):
subprocess.Popen(cmd, shell=True, executable='/bin/bash')
bash_command('comm -3 markets.json updatemarkets.json >> newpairs.json')But obviously this does not format it correctly.
I'm sure there's a Python solution which isn't hacked together like the above.
I've looked into Python libraries like difflib, as well as other bash options like diff and jq, but none seem to give me what I want in an efficient way.
Let me know what you think!
As the title indicates I'd like to get a diff of the keys (and only the keys, not values) of two json documents. Anyone here who have an idea about how to do so?