如何用jq对比两个JSON文件筛选transferIN变更的IP列表
解决方法
下面分两种常见的JSON结构给出对应的jq命令,确保只提取transferIN字段发生变化的节点IP:
情况1:JSON以IP为键的对象结构
假设两个文件的结构如下(键是节点IP,值包含transferIN/transferOUT字段):
// File1.json { "10.1.1.1/32": { "transferIN": 100, "transferOUT": 200 }, "10.1.1.2/32": { "transferIN": 150, "transferOUT": 250 } }
执行以下bash命令,输出用、分隔的目标IP列表:
jq -n --argfile f1 File1.json --argfile f2 File2.json ' [ ($f1 | keys) + ($f2 | keys) | unique[] | select( ($f1[$_].transferIN // null) != ($f2[$_].transferIN // null) ) ] | join("、") '
逻辑说明
($f1 | keys) + ($f2 | keys) | unique[]:获取两个文件中所有唯一的节点IP($f1[$_].transferIN // null):如果IP在文件中不存在或无transferIN字段,用null替代select(...):筛选出两个文件中transferIN值不相等的IPjoin("、"):将结果拼接成预期的字符串格式
如果需要只保留两个文件中都存在的IP(排除仅在单个文件出现的IP),修改select条件:
select( $f1[$_] != null and $f2[$_] != null and $f1[$_].transferIN != $f2[$_].transferIN )
情况2:JSON为节点对象数组结构
假设两个文件的结构如下(数组元素包含ip、transferIN、transferOUT字段):
// File1.json [ {"ip": "10.1.1.1/32", "transferIN": 100, "transferOUT": 200}, {"ip": "10.1.1.2/32", "transferIN": 150, "transferOUT": 250} ]
jq 1.6+版本命令(推荐)
利用INDEX函数快速将数组转为IP映射:
jq -n --argfile f1 File1.json --argfile f2 File2.json ' ($f1 | INDEX(.ip)) as $f1_map | ($f2 | INDEX(.ip)) as $f2_map [ ($f1_map | keys) + ($f2_map | keys) | unique[] | select( ($f1_map[$_].transferIN // null) != ($f2_map[$_].transferIN // null) ) ] | join("、") '
兼容旧版本jq(<1.6)命令
用reduce手动构建IP映射:
jq -n --argfile f1 File1.json --argfile f2 File2.json ' (reduce $f1[] as $item ({}; .[$item.ip] = $item)) as $f1_map | (reduce $f2[] as $item ({}; .[$item.ip] = $item)) as $f2_map [ ($f1_map | keys) + ($f2_map | keys) | unique[] | select( ($f1_map[$_].transferIN // null) != ($f2_map[$_].transferIN // null) ) ] | join("、") '
内容的提问来源于stack exchange,提问作者egrr
相关产品推荐
相关产品推荐

