如何通过单次JQ查询提取JSON中多层嵌套的目标字段
实现方案
合并后单次调用jq的代码(无重复输出,推荐)
a="112VEhPPMYF95neEEwwgnckHej4bgZ1roo13SMx18RSJxLq6JuiK" this_data="$(jq -r --arg a "${a}" '.data[] | select(.type == "poc_receipts_v1") | select( (.challengee != null and .challengee == $a) or (any(.path[]; .challengee != null and .challengee == $a)) )' file.json)"
逻辑说明
- 保留两次查询的公共前置筛选:仅处理
type为poc_receipts_v1的条目 - 用
or运算符将两次查询的独立筛选逻辑合并到同一个select语句中:- 第一部分匹配顶级字段
challengee等于目标值的条目,对应原第一次查询规则 - 第二部分通过
any()函数判断path数组中是否存在至少一个元素的challengee等于目标值,对应原第二次查询规则,同时避免直接展开path[]导致的条目重复输出
- 第一部分匹配顶级字段
- 全程仅读取解析一次JSON文件,可降低50%以上的CPU和IO开销
完全兼容原有输出逻辑的版本(允许重复输出)
如果你的业务逻辑需要和原有两次查询的输出完全一致(即当path数组中存在多个匹配元素时,同一个条目重复输出多次),可以使用以下写法:
a="112VEhPPMYF95neEEwwgnckHej4bgZ1roo13SMx18RSJxLq6JuiK" this_data="$(jq -r --arg a "${a}" '.data[] | select(.type == "poc_receipts_v1") | . as $current_item | (select($current_item.challengee != null and $current_item.challengee == $a)), ($current_item.path[] | select(.challengee != null and .challengee == $a) | $current_item)' file.json)"
内容的提问来源于stack exchange,提问作者Nick Hatfield
相关产品推荐
相关产品推荐

