如何在jq循环中引用当前位置并关联两个JSON文件的msg字段?
解决方法:用jq关联两个JSON文件的匹配日志条目
我来帮你搞定这个需求!要把log.json里的每条日志和messages.json中对应msg的条目关联起来,最高效的方式是先把messages的数据转成一个映射表,再批量匹配日志。下面是具体实现:
完整jq命令
jq --slurpfile messages messages.json ' # 将messages数组转换为{msg: out}的映射对象,方便快速查找 ($messages[0] | reduce .[] as $item ({}; .[$item.msg] = $item.out)) as $msgMap # 遍历log的每条日志,合并对应的out字段 | .[] | . + {out: $msgMap[.msg] // "No matching message found"} ' log.json
命令逻辑拆解
读取messages.json为数组:
--slurpfile messages messages.json参数会把messages.json中的所有JSON对象读取成一个数组,存储到变量$messages中($messages[0]就是这个数组本身)。构建msg到out的映射表:
$messages[0] | reduce .[] as $item ({}; .[$item.msg] = $item.out)用
reduce遍历messages数组,将每个条目的msg作为键、out作为值,构建一个键值对对象(比如{"Service starting up!": "The service has started"}),存到$msgMap变量里,这样后续查找能直接通过msg取值,不用反复遍历数组。处理log.json的每条日志:
.[] | . + {out: $msgMap[.msg] // "No matching message found"}.[]:遍历log.json的每一条日志(因为是多行JSON格式,jq默认会逐个处理,加上.[]确保每条都被遍历到). + {out: ...}:把原日志对象和新增的out字段合并$msgMap[.msg] // "No matching message found":如果找到对应msg的out值就使用它,找不到则用指定的默认文本(你可以改成null或者其他自定义默认值)
测试示例结果
用你提供的文件内容测试:
log.json内容
{"msg": "Service starting up!"} {"msg": "Running a job!"} {"msg": "Error detected!"}
messages.json内容
{"msg": "Service starting up!", "out": "The service has started"} {"msg": "Error detected!", "out": "Uh oh, there was an error!"} {"msg": "Service stopped", "out": "The service has stopped"}
运行命令后会输出:
{"msg":"Service starting up!","out":"The service has started"} {"msg":"Running a job!","out":"No matching message found"} {"msg":"Error detected!","out":"Uh oh, there was an error!"}
额外提示
- 如果你的
messages.json是单行数组格式(比如[{"msg": "...", ...}, ...]),这个命令同样适用,--slurpfile会正确读取为数组。 - 要是不需要默认值,直接写
$msgMap[.msg]即可,找不到匹配时out字段会显示null。
内容的提问来源于stack exchange,提问作者Belgabad
相关产品推荐
相关产品推荐

