Are there any command line utilities that can be used to find if two JSON files are identical with invariance to within-dictionary-key and within-list-element ordering?

Could this be done with jq or some other equivalent tool?

Examples:

These two JSON files are identical

A:

{
  "People": ["John", "Bryan"],
  "City": "Boston",
  "State": "MA"
}

B:

{
  "People": ["Bryan", "John"],
  "State": "MA",
  "City": "Boston"
}

but these two JSON files are different:

A:

{
  "People": ["John", "Bryan", "Carla"],
  "City": "Boston",
  "State": "MA"
}

C:

{
  "People": ["Bryan", "John"],
  "State": "MA",
  "City": "Boston"
}

那就是:

$ some_diff_command A.json B.json

$ some_diff_command A.json C.json
The files are not structurally identical

推荐答案

Since jq's comparison already compares objects without taking into account key ordering, all that's left is to sort all lists inside the object before comparing them. Assuming your two files are named a.json and b.json, on the latest jq nightly:

jq --argfile a a.json --argfile b b.json -n '($a | (.. | arrays) |= sort) as $a | ($b | (.. | arrays) |= sort) as $b | $a == $b'

This program should return "true" or "false" depending on whether or not the objects are equal using the definition of equality you ask for.

编辑:在某些边缘情况下,(.. | arrays) |= sort构造实际上并不能像预期的那样工作.This GitHub issue解释了原因,并提供了一些替代方案,例如:

def post_recurse(f): def r: (f | select(. != null) | r), .; r; def post_recurse: post_recurse(.[]?); (post_recurse | arrays) |= sort

应用于上述jq调用:

jq --argfile a a.json --argfile b b.json -n 'def post_recurse(f): def r: (f | select(. != null) | r), .; r; def post_recurse: post_recurse(.[]?); ($a | (post_recurse | arrays) |= sort) as $a | ($b | (post_recurse | arrays) |= sort) as $b | $a == $b'

Json相关问答推荐

在MongoDB中检索某个月份和年份的JSON文档

将带有::text[]的JSON数组转换未按预期工作

使用 jq 将非统一的 json 输出转换为汇总表

颠簸转换问题

转义 Haskell 记录的字段

如果值不存在,则将值插入 JSON 数组

在 postgresql 中将行转换为 json 对象

使用 JQ 从文件中删除重复的 JSON 块

使用 System.Text.Json 序列化记录成员

Powershell JSON 操作

JQuery,使用 GET 方法发送 JSON 对象

如何在golang中获取 struct 的json字段名称?

如何在返回对象的 Spring MVC @RestController @ResponseBody 类中响应 HTTP 状态代码?

将 Objective-C 对象序列化和反序列化为 JSON

将 CoffeeScript 项目转换为 JavaScript(不缩小)?

在 Webpack 中加载静态 JSON 文件

使用 jq 如何用其他名称替换键的名称

在 Android 中使用带有 post 参数的 HttpClient 和 HttpPost

如何使用 Serde 反序列化带有自定义函数的可选字段?

字符串格式 JSON 字符串给出 KeyError