使用jq的select筛选JSON数组元素并保留完整父对象结构的方法
如何用jq筛选JSON数组元素并保留完整父对象结构
我来帮你解决这个问题,其实用jq的**更新赋值运算符|=**就能轻松实现需求,不需要复杂的变量合并或者手动重建对象:
核心解决方案(匹配tactic == "impact")
直接执行这条jq命令:
.techniques |= [.[] | select(.tactic == "impact")]
命令解释
.首先选中整个根JSON对象(包含viewMode、hideDisabled、karma等所有父字段)techniques |= ...是jq的更新赋值语法,意思是把techniques字段的值替换成后面表达式计算出的结果[.[] | select(.tactic == "impact")]遍历原techniques数组,筛选出tactic等于impact的元素,重新组成新数组
测试验证
用你提供的输入JSON:
{ "viewMode": 0, "hideDisabled": false, "techniques": [ { "name": "john", "tactic": "reconnaissance" }, { "name": "jane", "tactic": "impact" }, { "name": "jill", "tactic": "execution" } ], "karma": "yes" }
执行命令后,输出完全符合你的期望:
{ "viewMode": 0, "hideDisabled": false, "techniques": [ { "name": "jane", "tactic": "impact" } ], "karma": "yes" }
拓展:支持!=的筛选场景
如果需要筛选tactic不等于某个值的元素,只需要修改select里的条件即可,比如筛选tactic != "reconnaissance":
.techniques |= [.[] | select(.tactic != "reconnaissance")]
执行后会保留tactic为impact和execution的元素,同时所有父字段依然完整保留。
为什么你之前的尝试会出错?
你之前用变量保存筛选后的techniques再合并的方法,错误在于$a + [.]中,$a是一个仅包含techniques字段的对象,而[.]是包含整个根对象的数组,对象和数组类型不匹配,所以jq报错。而用|=的方式是直接在原对象上修改指定字段,其他字段会自动保留,完全不需要手动处理合并逻辑,既简洁又不会出错。
内容的提问来源于stack exchange,提问作者user2480552
相关产品推荐
相关产品推荐

