如何使用jq将指定应用的策略键值对合并为单个JSON对象
问题定位
你的输出不符合预期主要来自两方面的问题:
- 流聚合逻辑缺失:你使用
.policies[]把策略数组拆成了独立的元素处理流,jq会对每个流元素单独输出结果,自然会产生两个独立的JSON对象,没有做合并聚合的操作。 - 动态键的语法误用:如果严格按照你写的
{".name" : .orderNumber}执行,jq会把双引号包裹的.name当成静态字符串键名,根本不会动态取策略的name值——要拿表达式的结果当动态键,必须把表达式用括号括起来,这是jq写对象结构时最常见的语法坑。
可直接复用的正确实现
三个常用写法都能直接输出你要的单个目标JSON对象,按使用场景选就行:
写法1:数组映射后合并,最易理解
jq '.application[] | select(.name=="app1") | .policies | map({(.name): .orderNumber}) | add' 你的json文件
逻辑拆解:
- 先筛选出name为app1的应用对象
- 不拆分策略数组,直接给数组内每个策略元素生成单键小对象
- 最后用内置的
add函数把数组里的所有小对象合并成单个大对象,输出结果就是{"pol_1":"10", "pol_2":"20"}
写法2:标准条目转换,可读性更强
jq '.application[] | select(.name=="app1") | .policies | map({key: .name, value: .orderNumber}) | from_entries' 你的json文件
逻辑拆解:把每个策略转成jq标准的{key, value}结构的键值对条目,再通过内置from_entries函数直接生成目标JSON对象,策略数量多的时候代码可读性更好。
写法3:流累积写入,适配大数组场景
jq '.application[] | select(.name=="app1") | reduce .policies[] as $p ({}; .[$p.name] = $p.orderNumber)' 你的json文件
逻辑拆解:从空对象开始,每遍历到一个策略元素就把对应的键值对写入对象,遍历完成后直接输出聚合好的单对象,不需要在内存里暂存所有中间小对象,适合处理大体积的数组场景。
内容的提问来源于stack exchange,提问作者orange-lily
相关产品推荐
相关产品推荐

