如何用jq合并两个含相同数组结构的JSON文件?
使用jq合并同结构JSON文件中的数组
问题场景
有两个结构一致的JSON文件,需要将对应字段的数组合并(保留所有元素,而非覆盖或重复):
file1.json:
{ "veg": { "trolley": [ "potato" ], "total_items": [ 1 ] } }
file2.json:
{ "veg": { "trolley": [ "lettuce", "tomato" ], "total_items": [ 2 ] } }
期望输出:
{ "veg": { "trolley": [ "potato", "lettuce", "tomato" ], "total_items": [ 1, 2 ] } }
解决方案
针对特定结构的直接合并
如果JSON结构固定,可直接指定字段进行数组追加:
jq -s '.[0].veg.trolley += .[1].veg.trolley | .[0].veg.total_items += .[1].veg.total_items | .[0]' file1.json file2.json
命令解释:
-s:将两个输入文件读取为一个JSON数组,.[0]对应file1.json内容,.[1]对应file2.json内容+=:将第二个文件的数组元素追加到第一个文件的对应数组中.[0]:最终输出合并后的第一个元素(即完成合并的JSON对象)
通用递归合并(适配任意层级数组)
如果需要处理任意层级的同结构JSON,可使用递归逻辑合并所有数组字段:
jq -s 'reduce .[] as $curr ({}; reduce ($curr | keys_unsorted[]) as $key (.; if .[$key] | type == "array" and $curr[$key] | type == "array" then .[$key] += $curr[$key] elif .[$key] | type == "object" and $curr[$key] | type == "object" then .[$key] = (.[$key] * $curr[$key] | walk(if type == "array" then . + .[:0] else . end) | reduce .[] as $item ({}; . * $item)) else .[$key] = $curr[$key] end ) )' file1.json file2.json
常见方法失效原因
jq -s 'add':对象合并时,后一个文件的数组会直接覆盖前一个文件的同名字段,而非追加元素- 错误使用
|= . +:若在顶层对象执行该操作,会导致整个对象重复,而非仅数组元素追加
内容的提问来源于stack exchange,提问作者user486670
相关产品推荐
相关产品推荐

