原创:打码日记(微信公众号ID:codelogs),欢迎分享,转载请保留出处。

简介#

近期,为了给一个核心系统减负,组内决定将一些调用量大的查询接口迁移到另一个系统,由于接口逻辑比较复杂,为了保证接口逻辑一致,我们决定将一周内的请求参数在两个接口重放,并用脚本校验两边接口的响应结果。
接口返回数据是json结构的,本想用icdiff、jq来实现,但时间紧迫一时没想出来,同事用python脚本实现了这个对比,但后来又仔细想了想,找出了使用icdiff、jq实现的方法。

icdiff对比文本#

对于普通的文本对比,使用diff命令即可完成,但icdiff比diff更好用,对比结果也会更加直观。

$ text1='{"name":"apple","item_no":2}'
$ text2='{"name":"a apple","item_no":2}'
$ icdiff <(echo "$text1") <(echo "$text2")

但如果用jq格式化一下再对比,看起来会更加清晰一些。

$ icdiff <(echo "$text1"|jq .) <(echo "$text2"|jq .)

但是有时json数据可能会出现数据一样,但key的顺序不一致的问题,比如:

$ text1='{"name":"apple","item_no":2}'
$ text2='{"item_no":2,"name":"apple"}'
$ icdiff <(echo "$text1"|jq .) <(echo "$text2"|jq .)


像对象转json这种操作,是有可能出现不同机器上返回json的key顺序不同的。

好在jq提供了-S选项,可对输出json的key排序,如下:

$ icdiff <(echo "$text1"|jq -S .) <(echo "$text2"|jq -S .)

本以为这样就解决了所有问题,但在脚本运行过程中,我们又发现了新情况,json中的数组项,顺序可能不一致,如下:

$ text1='{
"order_id": 121345435624,
"waybills": [
{
"waybill_id": 1,
"name": "package1",
"items": [
{
"name": "orange",
"item_no": 1
},
{
"name": "apple",
"item_no": 2
}
]
},
{
"waybill_id": 2,
"name": "package2",
"items": [
{
"name": "pear",
"item_no": 3
},
{
"name": "banana",
"item_no": 4
}
]
}
]
}'
$ text2='{
"order_id": 121345435624,
"waybills": [
{
"waybill_id": 2,
"name": "package2",
"items": [
{
"name": "banana",
"item_no": 4
},
{
"name": "pear",
"item_no": 3
}
]
},
{
"waybill_id": 1,
"name": "package1",
"items": [
{
"name": "orange",
"item_no": 1
},
{
"name": "apple",
"item_no": 2
}
]
}
]
}'
$ icdiff <(echo "$text1"|jq -S .) <(echo "$text2"|jq -S .)


因为icdiff没法识别这种顺序区别,它只是逐行进行对比的,虽然两个json逻辑上是一样的,但它区别不出来。
程序中以下情况会造成这种顺序区别:

  1. 从数据库中查询数据时,如果SQL没有order by语句,那么返回结果的顺序是不确定的。
  2. 如果数据是在Map中,当用values()变换成List返回数据时,返回结构的顺序也是不确定的。

要解决这种情况还真挺麻烦的,因为需要对json中的数组进行排序,然后再进行对比,之前就是这里想不出来怎么实现。
但在后来,我又仔细的看了看jq的man文档,发现了一个有用的函数walk,然后就试了试,还真发现可以实现。

$ json_sort='walk(if type == "array" and length >0 then (if .[0].item_no then sort_by(.item_no) elif .[0].waybill_id then sort_by(.waybill_id) else. end) else . end)'
$ icdiff <(echo "$text1"|jq -S "$json_sort") <(echo "$text2"|jq -S "$json_sort")

总结#

Linux命令结合起来,总能产生更大的作用,当然这也需要付出一些折腾时间啊。

往期内容#

Linux文本命令技巧(下)
Linux文本命令技巧(上)
原来awk真是神器啊
好用的parallel命令
常用网络命令总结

作者:打码日记

出处:https://www.cnblogs.com/codelogs/p/16060148.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

[转帖] jq实现json文本对比的更多相关文章

  1. XML与JSON的对比

    XML与JSON的对比 1.各自定义 XML 扩展标记语言 (Extensible Markup Language, XML) ,用于标记电子文件使其具有结构性的标记语言,可以用来标记数据.定义数据类 ...

  2. JSON C# Class Generator是一个从JSON文本中生成C#内的应用程序

    JSON C# Class Generator是一个从JSON文本中生成C#内的应用程序 .NET平台开源项目速览(18)C#平台JSON实体类生成器JSON C# Class Generator   ...

  3. jq处理JSON数据, jq Manual (development version)

    jq 允许你直接在命令行下对 JSON 进行操作,包括分片.过滤.转换等等.让我们通过几个例子来说明 jq 的功能:一.输出格式化,漂亮的打印效果如果我们用文本编辑器打开 JSON,有时候可能看起来会 ...

  4. 使用 Json.Net 对Json文本进行 增删改查

    JSON 已经成为当前主流交互格式, 如何在C#中使用 Json.Net 对Json文本进行 增删改查呢?见如下代码 #region Create (从零创建) public static strin ...

  5. php 两段文本对比,不同的文字显示高亮

    php 两段文本对比,不同的文字显示高亮[下面这个只能区分错误后面的..]   <?php $str1 ="MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwgg ...

  6. JSON文本转换为JSONArray 转换为 List<Object>

    package com.beijxing.TestMain; import java.io.File; import java.io.IOException; import java.util.Arr ...

  7. json文本装换为JSONArray

    package com.beijxing.TestMain; import java.io.File; import java.io.IOException; import org.apache.co ...

  8. 一个Json结构对比的Python小工具兼谈编程求解问题

    先上代码. jsondiff.py #!/usr/bin/python #_*_encoding:utf-8_*_ import argparse import json import sys rel ...

  9. 21SpringMvc_异步发送表单数据到Bean,并响应JSON文本返回(这篇可能是最重要的一篇了)

    这篇文章实现三个功能:1.在jsp页面点击一个按钮,然后跳转到Action,在Action中把Emp(int id ,String salary,Data data)这个实体变成JSON格式返回到页面 ...

  10. 高性能JSON工具-FastJson处理超大JSON文本

    使用阿里开源类库FastJson,当需要处理超大JSON文本时,需要Stream API,在fastjson-1.1.32版本中开始提供Stream API.文档参考GitHub:https://gi ...

随机推荐

  1. 宝兰德应用服务器软件与华为云GaussDB完成兼容互认证

    摘要:北京宝兰德软件股份有限公司携手华为云完成宝兰德应用服务器软件9.5与GaussDB数据库兼容性测试,并获得华为云授予的技术认证书. 本文分享自华为云社区<宝兰德应用服务器软件与华为云Gau ...

  2. 详解KubeEdge边缘网络项目EdgeMesh

    摘要:本文带大家进一步了解 EdgeMesh 的进展以及未来的规划. 本文分享自华为云社区<走向成熟的KubeEdge边缘网络项目EdgeMesh详解>,作者:华为云云原生团队 王杰章 . ...

  3. AI论文解读:基于Transformer的多目标跟踪方法TrackFormer

    摘要:多目标跟踪这个具有挑战性的任务需要同时完成跟踪目标的初始化.定位并构建时空上的跟踪轨迹.本文将这个任务构建为一个帧到帧的集合预测问题,并提出了一个基于transformer的端到端的多目标跟踪方 ...

  4. CANN 5.0硬核技术抢先看

    摘要:2021年12月,CANN5.0版本也将与大家正式见面,通过软硬件协同优化,该版本将会实现训练性能再翻倍,凭实力展现AI领域的「中国速度」! 本文分享自华为云社区<CANN 5.0硬核技术 ...

  5. 当物联网遇上云原生:K8s向边缘计算渗透中

    摘要:K8s正在向边缘计算渗透,它为边缘侧的应用部署提供了便利性,在一定程度上转变了边缘应用与硬件之间的关系,将两者的耦合度降低. 本文分享自华为云社区<云原生在物联网中的应用[拜托了,物联网! ...

  6. Hadoop中mapreduce作业日志是如何生成的

    摘要:本篇博客介绍了hadoop中mapreduce类型的作业日志是如何生成的.主要介绍日志生成的几个关键过程,不涉及过多细节性的内容. 本文分享自华为云社区<hadoop中mapreduce作 ...

  7. PPT 工作需求:如何利用PPT做活动海报&H5?

    PPT 工作需求:如何利用PPT做活动海报? 图片素材 + 字体 + 封面排版 PPT 工作需求:如何利用PPT制作H5? https://www.maka.im/muban http://www.p ...

  8. 一个非常轻量级的 Web API Demo

    一个非常轻量级的 Web API Demo,代码量很少,实现了方法拦截器,token校验,异常拦截器,缓存 创建项目:如果选择Web API,项目中东西会比较多,这里选择Empty,把下面的Web A ...

  9. [Docker] Mac M2 – no such file or directory: /var/lib/docker/volumes ,找不到var/lib/docker/volumes (已解決)

    Mac M2 Pro Docker 24.0.6 $ docker volume inspect 14dfdb65fb7075d91b2004c979a3591df54bcc1303ff3ca96a3 ...

  10. 简单的winform学生管理系统Demo

    界面效果 练习重点 1. 关系表的创建 2. 增删改查的操作,及sqlhelper的封装 3. 跨页面数据传递,编辑页数据提交后数据局步刷新到列表数据 项目源码 FrmStuddentList pub ...