如何用jq合并多个JSON对象中同一键对应的数组?
问题描述
我查了一些相关问题,但要么需要提前知晓对象的键名,要么会出现数组被覆盖的问题,还有的语法超出我的理解范围,不知道怎么修改reduce语句来实现需求。
输入格式
有一个包含多个JSON对象块的文件,每个顶层对象仅有一个键,对应的值为数组,格式示例如下:
{ "SomeCategory": [ { "Key": "value1" # 第一个条目 }, { "Key": "value2" }, { ... }, { "Key": "valueA" } ] } { "SomeCategory": [ { "Key": "valueA+1" }, { "Key": "valueA+2" }, { ... }, { "Key": "valueA+B" # 最后一个条目 } ] } { ... 重复更多类似对象 ... }
预期输出
将所有顶层对象块合并为一个,对应键的所有数组合并到一起,结果如下:
{ "SomeCategory": [ { "Key": "value1" # 第一个条目 }, { "Key": "value2" }, { ... }, { "Key": "valueA+B" # 最后一个条目 } ] }
尝试过的命令
试过以下reduce合并命令,但会出现数组被覆盖的问题,最终只保留最后一个顶层对象:
jq -n 'reduce inputs as $foo ({}; . *= $foo)'
额外说明
- 所有顶层对象的唯一键完全相同,但无法提前知晓该键的具体名称;
- 数组内的对象包含多个键,此处仅展示了
Key; - 数组内对象的键一致,但值均为唯一,无需合并这些对象本身。
解决方案
使用reduce遍历所有输入对象,针对每个对象的键值对,将数组追加到结果对象对应键的数组中,具体命令如下:
jq -n 'reduce inputs as $obj ({}; ($obj | keys[]) as $key; .[$key] += $obj[$key])'
命令解释
-n:让jq从空输入状态启动,避免自动输出第一个输入对象;reduce inputs as $obj ({}; ...):遍历所有输入的JSON对象,初始结果为空对象{};($obj | keys[]) as $key:提取当前输入对象的唯一键(因每个输入对象仅含一个键);.[$key] += $obj[$key]:将当前对象的数组值追加到结果对象对应键的数组中,若键不存在则自动创建。
该命令无需提前知晓键名,且能避免数组被覆盖,完美实现数组合并需求。
内容的提问来源于stack exchange,提问作者Ti Strga
相关产品推荐
相关产品推荐

