基于JQ工具实现两个JSON文件键值匹配与新JSON生成的技术求助
解决用JQ合并两个JSON文件的问题
别着急,刚接触JQ确实容易绕晕,我来一步步帮你搞定这个需求!
首先咱们理清楚关联逻辑:
- 文件1里的每个对象通过
key和文件2的对象关联 - 最终要按文件1的
id分组,每个id下是文件1的name对应文件2里同key的所有name组成的数组
具体JQ命令
你可以直接用这条命令,把file1.json和file2.json替换成你的实际文件名:
jq -n --slurpfile f1 file1.json --slurpfile f2 file2.json ' # 先把文件2转成 key -> [name数组] 的映射 $f2 | group_by(.key) | map({key: .[0].key, names: [.[].name]}) | INDEX(.key) as $keyToNames # 然后处理文件1,按id分组构建最终结构 | $f1 | group_by(.id) | map( { (.[0].id): ( . | map({ (.[].name): $keyToNames[.[].key].names }) | add ) } ) | add '
拆解命令逻辑
我把每个部分的作用拆解开,方便你理解:
--slurpfile f1 file1.json:把文件1的所有JSON对象读成一个数组$f1$f2 | group_by(.key) | map({key: .[0].key, names: [.[].name]}) | INDEX(.key) as $keyToNames:- 先把文件2按
key分组 - 把每组转成
key对应name数组的结构 - 用
INDEX把这个结构转成以key为键的对象,方便快速查找
- 先把文件2按
$f1 | group_by(.id):把文件1按id分组,这样每个组里的对象都是同一个id下的map({(.[0].id): (...)}):为每个id组创建一个键值对,键是id的值. | map({(.[].name): $keyToNames[.[].key].names}) | add:- 遍历当前
id组里的每个对象,创建以name为键、对应文件2的name数组为值的对象 - 用
add把这些小对象合并成一个大对象
- 遍历当前
| add:最后把所有id对应的对象合并成最终的顶层对象
验证结果
运行这条命令后,输出就会和你期望的完全一致:
{ "x": { "foo": [ "a", "b" ], "bar": [ "c", "d" ] }, "y": { "baz": [ "e" ] } }
如果还有不清楚的地方,可以随时问我!
内容的提问来源于stack exchange,提问作者Samrat
相关产品推荐
相关产品推荐

