一尘不染

使用jq或备用命令行工具比较JSON文件

json

是否有任何命令行实用程序可用于查找两个JSON文件是否相同,且字典内键和列表内元素顺序不变?

可以使用jq其他等效工具完成此操作吗?

例子:

这两个JSON文件是相同的

A

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

B

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

但是这两个JSON文件是不同的:

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

阅读 235

收藏
2020-07-27

共1个答案

一尘不染

由于jq的比较已经在不考虑键顺序的情况下比较了对象,因此剩下的就是在比较对象之前对对象中的所有列表进行排序。假设您的两个文件在每晚的最新jq上分别命名为a.jsonb.json

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

该程序应使用您要求的相等性定义取决于对象是否相等,返回“ true”或“ false”。

编辑:(.. | arrays) |= sort在某些情况下,构造实际上并没有按预期工作。这个GitHub问题解释了原因并提供了一些替代方法,例如:

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'
2020-07-27