如何使用jq完全排序任意JSON? [英] How can I completely sort arbitrary JSON using jq?

查看:292
本文介绍了如何使用jq完全排序任意JSON?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想比较两个JSON文本文件.不幸的是,它们是按任意顺序构造的,因此当它们在语义上相同时,我会得到差异.我想使用jq(或其他任何一种)以任何完整的顺序对它们进行排序,以消除仅由于元素排序而引起的差异.

I want to diff two JSON text files. Unfortunately they're constructed in arbitrary order, so I get diffs when they're semantically identical. I'd like to use jq (or whatever) to sort them in any kind of full order, to eliminate differences due only to element ordering.

-sort-keys解决了一半的问题,但它不能对数组进行排序.

--sort-keys solves half the problem, but it doesn't sort arrays.

我不太了解jq,也不知道如何编写保留所有数据的jq递归过滤器;任何帮助将不胜感激.

I'm pretty ignorant of jq and don't know how to write a jq recursive filter that preserves all data; any help would be appreciated.

我意识到逐行'diff'输出不一定是比较两个复杂对象的最佳方法,但是在这种情况下,我知道这两个文件非常相似(几乎相同)并且逐行差异对我而言很好.

I realize that line-by-line 'diff' output isn't necessarily the best way to compare two complex objects, but in this case I know the two files are very similar (nearly identical) and line-by-line diffs are fine for my purposes.

使用jq或其他命令行工具来区分JSON文件可以回答一个非常相似的问题,但不会显示出差异.另外,我想保存排序后的结果,所以我真正想要的只是一个用于对JSON进行排序的过滤程序.

Using jq or alternative command line tools to diff JSON files answers a very similar question, but doesn't print the differences. Also, I want to save the sorted results, so what I really want is just a filter program to sort JSON.

推荐答案

这里是使用通用函数 sorted_walk/1 的解决方案(之所以如此命名,原因如下所述). >

Here is a solution using a generic function sorted_walk/1 (so named for the reason described in the postscript below).

normalize.jq:

normalize.jq:

# Apply f to composite entities recursively using keys[], and to atoms
def sorted_walk(f):
  . as $in
  | if type == "object" then
      reduce keys[] as $key
        ( {}; . + { ($key):  ($in[$key] | sorted_walk(f)) } ) | f
  elif type == "array" then map( sorted_walk(f) ) | f
  else f
  end;

def normalize: sorted_walk(if type == "array" then sort else . end);

normalize

使用bash的示例:

diff <(jq -S -f normalize.jq FILE1) <(jq -S -f normalize.jq FILE2)

POSTSCRIPT:第一次发布此响应后,修订了walk/1的内置定义:现在使用keys_unsorted而不是keys.

POSTSCRIPT: The builtin definition of walk/1 was revised after this response was first posted: it now uses keys_unsorted rather than keys.

这篇关于如何使用jq完全排序任意JSON?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆