求助:如何用jq合并JSON对象?需处理IP与键值对合并
使用jq合并JSON对象:IP去重与键值对整合
原始JSON数据
[ { "name": "test_name", "cpu": "1", "ip": "192.168.0.1", "kv_key": "test2_key", "kv_value": "test2_value", "location": "here" }, { "name": "test_name", "cpu": "1", "ip": "192.168.0.2", "kv_key": "test1_key", "kv_value": "test1_value", "location": "here" }, { "name": "test_name", "cpu": "1", "ip": "192.168.0.1", "kv_key": "test2_key", "kv_value": "test2_value", "location": "here" }, { "name": "test_name", "cpu": "1", "ip": "192.168.0.1", "kv_key": "test3_key", "kv_value": "test3_value", "location": "here" } ]
期望合并结果
[ { "name": "test_name", "cpu": "1", "ip": [ "192.168.0.1", "192.168.0.2" ], "key_value": [ { "test1_key": "test1_value", "test2_key": "test2_value", "test3_key": "test3_value" } ], "location": "here" } ]
完整解决方案命令
jq 'group_by(.name) | map( first + {ip: [.[].ip] | unique} + {key_value: [reduce .[] as $item ({}; . + {($item.kv_key): $item.kv_value})]} | del(.kv_key, .kv_value) )' <<< "${json}"
命令分步解释
- 按
name分组:group_by(.name)将所有同名称的JSON对象归为一组,这里所有数据的name均为test_name,因此只会生成一个分组。 - 保留公共字段:
first提取分组内第一个对象的公共字段(name、cpu、location),这些字段在所有对象中值一致,无需额外处理。 - IP去重合并:
{ip: [.[].ip] | unique}提取分组内所有ip值,通过unique去重后转为数组格式。 - 整合键值对:
{key_value: [reduce .[] as $item ({}; . + {($item.kv_key): $item.kv_value})]}使用reduce遍历分组内每个对象,将kv_key作为键、kv_value作为值合并成单个对象,再包裹到数组中以匹配期望结构。 - 清理冗余字段:
del(.kv_key, .kv_value)删除原对象中残留的kv_key和kv_value字段,避免结果中出现冗余数据。
对原有命令的修正说明
你之前的命令map(. |= (group_by(.name) | map(first + {ip: map(.ip)})))存在结构问题:group_by应作用于整个JSON数组,而非单个对象内部。调整后先整体分组,再对每组做字段处理,即可同时实现IP合并和键值对整合。
内容的提问来源于stack exchange,提问作者amans san
相关产品推荐
相关产品推荐

