如何用jq筛选JSON数组中field2为true的元素并获取其长度?
问题描述
在bash脚本中有如下JSON对象:
obj='{ "Obj": [{"field1": a, "field2": true}, {"field1": b, "field2": true}, {"field1": c, "field2": false}, {"field1": d, "field2": true}]}'
需求是筛选出其中field2为true的元素组成合法JSON数组,再获取该数组的长度(示例中应为3)。
尝试以下代码后得到的元素无逗号分隔,无法使用jq length:
r=`echo $obj | jq '.Obj | select(.field2 == true)'` r="[$r]" echo $r
输出结果为:
[ {"field1": a, "field2": true} {"field1": b, "field2": true} {"field1": d, "field2": true}]
正确实现方法
你之前的写法错误在于:select(.field2 == true)会把数组拆成单个对象的输出流,而非数组结构,手动包裹[]自然不会自动添加逗号。正确的做法是让jq直接返回过滤后的合法数组,再按需获取长度。
方法1:用map过滤数组并返回数组
直接对Obj数组使用map,筛选符合条件的元素,返回完整数组:
# 生成合法JSON数组 echo "$obj" | jq '.Obj | map(select(.field2 == true))'
输出会是带逗号分隔的合法数组:
[ {"field1": a, "field2": true}, {"field1": b, "field2": true}, {"field1": d, "field2": true} ]
如果要直接获取数组长度,在命令后追加.length即可:
echo "$obj" | jq '.Obj | map(select(.field2 == true)) | length'
输出结果:3
方法2:展开数组过滤后重新包裹
先展开数组元素,筛选后再重新组合成数组:
# 生成合法JSON数组 echo "$obj" | jq '[.Obj[] | select(.field2 == true)]'
同样能得到合法数组,获取长度的写法:
echo "$obj" | jq '[.Obj[] | select(.field2 == true)] | length'
注意事项
原始JSON中的a、b等如果是字符串类型,需要添加双引号(如"field1": "a"),否则jq会将其识别为未定义变量导致报错。
内容的提问来源于stack exchange,提问作者user2175783
相关产品推荐
相关产品推荐

