jq为select语句添加多条件筛选返回匹配完整JSON对象
jq多条件过滤时如何保留符合要求的完整JSON对象
问题场景
现有如下JSON内容(为多个JSON对象拼接的JSONL格式文件):
{ "name": "pp-site1-r1-n2", "state": "Monitored", "stateReason": "NotApplicable" } { "name": "bb-site2-3par-ilo", "state": "Monitored", "stateReason": "NotApplicable" } { "name": "tm-site1-r3-n4-ilo", "state": "ProfileError", "stateReason": "NotApplicable" } { "name": "tm-site3-r1-n6-ilo", "state": "ProfileApplied", "stateReason": "NotApplicable" }
服务器的正常状态为ProfileApplied,最初需要查询所有非正常状态的服务器条目,执行命令:
jq '. | select(.state!="ProfileApplied")'
返回结果如下,符合预期:
{ "name": "pp-site1-r1-n2", "state": "Monitored", "stateReason": "NotApplicable" } { "name": "bb-site2-3par-ilo", "state": "Monitored", "stateReason": "NotApplicable" } { "name": "tm-site1-r3-n4-ilo", "state": "ProfileError", "stateReason": "NotApplicable" }
后续新增过滤要求:排除名称包含3par的设备,最初修改的查询命令为:
jq '. | select(.state!="ProfileApplied") | .name | contains("3par")|not'
执行后仅返回如下布尔值:
true false true
返回的布尔逻辑是正确的,但无法获取结果为true对应的完整JSON对象。
解决方法
问题根源在管道逻辑:当你在管道中传入.name时,当前处理的上下文已经从完整JSON对象替换成了name字段的字符串值,后续判断完成后自然只会输出布尔结果,丢失了原对象数据。
把两个过滤条件都放到select()过滤器内部,用逻辑与连接即可,不需要单独把name字段抽出来判断:
jq 'select(.state != "ProfileApplied" and (.name | contains("3par") | not))'
命令说明:
select()会保留所有括号内判断结果为真的完整JSON对象- 两个判断条件同时生效:
- 状态不等于正常状态
ProfileApplied - 名称字段不包含
3par字符串
- 状态不等于正常状态
执行后即可得到预期结果:
{ "name": "pp-site1-r1-n2", "state": "Monitored", "stateReason": "NotApplicable" } { "name": "tm-site1-r3-n4-ilo", "state": "ProfileError", "stateReason": "NotApplicable" }
内容的提问来源于stack exchange,提问作者user2664304
相关产品推荐
相关产品推荐

