如何使用jq根据外层对象值过滤内层对象数组?
用jq筛选嵌套数组中与外层属性值匹配的对象
没问题,这在jq里是个很常见的需求,我给你用实际例子一步步说明怎么实现。
首先假设你的输入JSON数据是类似这样的(你可以根据自己的实际结构调整):
{ "foo": "target-value", "stuff": [ {"foo": "target-value", "data": "match-1"}, {"foo": "other-value", "data": "no-match"}, {"foo": "target-value", "data": "match-2"} ] }
核心实现命令
jq '.foo as $outer_foo | .stuff[] | select(.foo == $outer_foo)' input.json
命令逐段解释
.foo as $outer_foo:先把外层对象的foo属性值保存到变量$outer_foo里,这样后面遍历数组时能随时引用这个外层基准值,避免上下文切换后找不到原数据。.stuff[]:遍历stuff数组中的每一个元素,把jq的上下文切换到单个数组对象上。select(.foo == $outer_foo):筛选出当前数组元素的foo值和外层保存的$outer_foo完全相等的对象,不符合条件的会被直接过滤掉。
输出形式调整
如果希望结果是一个完整的JSON数组(而不是逐个输出匹配的对象),可以把整个筛选逻辑包裹在数组括号里:
jq '[.foo as $outer_foo | .stuff[] | select(.foo == $outer_foo)]' input.json
运行结果示例
用第一个命令的输出是两个独立的匹配对象:
{"foo": "target-value", "data": "match-1"} {"foo": "target-value", "data": "match-2"}
用数组包裹的命令输出则是一个结构化的数组:
[ {"foo": "target-value", "data": "match-1"}, {"foo": "target-value", "data": "match-2"} ]
另外还有一种更简洁的写法,不用显式定义变量,但可读性稍差:
jq '.stuff[] | select(.foo == ($foo = .foo))' input.json
我更推荐第一种用变量的写法,尤其是处理复杂嵌套结构时,能清晰区分内外层数据,不容易出错。
内容的提问来源于stack exchange,提问作者2rs2ts
相关产品推荐
相关产品推荐

