原创:打码日记(微信公众号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(DWS)深度技术解读:融、快、大、稳、易

    摘要:云原生数据仓库GaussDB(DWS)架构师应邀为大家解读数仓深度技术. "云原生"在2020年成为备受瞩目的热词,云原生在确保企业数字化转型中资源快速供给.按需使用的同时, ...

  2. 华夏天信携手华为云开天aPaaS,打造安全、高效、节能的主煤流运输系统

    摘要:基于开天aPaaS集成工作台,主煤流运输系统如何实现多源异构数据融合.皮带物料和人员违章的智能感知,以及皮带的智能控制.灵活架构.高效集成.快速开发! 本文分享自华为云社区<华夏天信携手华 ...

  3. ModelBox姿态匹配:抖抖手动动脚勤做深呼吸

    摘要:本案例使用Windows版本的ModelBox SDK进行二次开发,主要是针对姿态匹配案例开发实践. 本文分享自华为云社区<姿态匹配:抖抖手动动脚勤做深呼吸>,作者:吴小鱼. 在之前 ...

  4. 云图说丨每个成功的业务系统离不开API网关(APIG)的保驾护航

    摘要:华为云API网关(APIG)是为企业开发者及合作伙伴提供的高性能.高可用.高安全的API托管服务, 帮助企业轻松构建.管理和部署不同规模的API. 本文分享自华为云社区<[云图说]第243 ...

  5. hadoop清空回收站时间设置

    在hadoop执行删除文件命令 如果不带 -skipTrash 文件是进入了回收站 空间并不会被释放 会隔一段时间才被删除 设置该时间位置为: core-site.xml fs.trash.inter ...

  6. 代码混淆工具ipaguard:如何使用ipaguard保护和混淆iOS应用程序代码

    ​ 转载:怎么保护苹果手机移动应用程序ios ipa文件中的代码? 目录 转载:怎么保护苹果手机移动应用程序ios ipa文件中的代码? 代码混淆步骤 1. 选择要混淆保护的ipa文件 2. 选择要混 ...

  7. PPT 放映时字体缺失怎么办

    PPT 放映时字体缺失怎么办 文字转成图片 嵌入字体 没有版权的不给嵌入 安装字体 http://www.hellofont.cn 在线使用安装字体

  8. python jira 取提出指向未解决的问题

    #!/usr/bin/python # -*- coding: utf-8 -*- import sys, os,time,requests,datetime import schedule from ...

  9. ZK--简介,部署

    官网:https://zookeeper.apache.org/ 本文zk版本:3.7.0 一.简介 ZooKeeper 是一个高可用的分布式数据管理与系统协调软件,它可以为分布式应用提供状态同步.配 ...

  10. POJ 2726、POJ3074 :数独(二进制DFS)

    题目链接:https://ac.nowcoder.com/acm/contest/1014/B 题目描述 In the game of Sudoku, you are given a large 9 ...