解决jq处理JSON重复结果问题:筛选含change:false的子组
问题:筛选包含指定属性的JSON子组
我想要编辑JSON文件,仅保留包含任意标记为"change":false的attributes的子组。给定的JSON数据如下:
{"group":{ "subgroup1":{ "attributes":[ { "change":false, "name":"Name"}, { "change":false, "name":"SecondName"}, ], "id":1, "name":"MasterTest"}, "subgroup2":{ "attributes":[ { "change":true, "name":"Name" }, { "change":false, "name":"Newname" } ], "id":2, "name":"MasterSet"}, }}
我尝试使用命令:
cat test.json | jq '.group[] | select (.attributes[].change==false)'
该命令能输出所需子组,但结果存在重复。请问如何解决此问题?或者是否有其他命令可实现需求?
解决方案
重复原因
你当前的命令里,.attributes[]会遍历子组下的每一个attributes元素,只要有一个元素满足change==false,就会把当前子组返回一次。如果子组里有N个符合条件的attributes元素,子组就会被重复输出N次。
正确命令
要避免重复,只需要判断子组的attributes中存在任意一个change==false的元素即可,用jq的any()函数就能实现这个逻辑:
输出单个子组对象(与原命令输出结构一致,无重复)
cat test.json | jq '.group[] | select(any(.attributes[]; .change == false))'
保留原JSON结构(仅保留group下符合条件的子组)
如果想保留原JSON的层级结构,而不是单独输出子组,可以用with_entries过滤group下的键值对:
cat test.json | jq '.group |= with_entries(select(any(.value.attributes[]; .change == false)))'
命令说明
any(.attributes[]; .change == false):遍历子组的attributes数组,只要有一个元素满足.change == false,就返回true,select就会保留这个子组。with_entries(...):用来处理对象的键值对,这里只保留group中值(子组)符合条件的条目,最终输出的JSON结构和原数据一致,只是过滤掉了不符合条件的子组。
内容的提问来源于stack exchange,提问作者strmgr
相关产品推荐
相关产品推荐

