如何用jq递归选择含description键的对象的键名?
解决jq筛选包含description键的对象对应的键的问题
我来帮你搞定这个jq筛选的问题!你需要从给定的JSON结构里,找出所有值是包含description键的对象对应的键,最终整理成数组["normal", "one", "two"],对吧?
核心解决方案
直接用下面这个jq表达式就能得到你想要的结果:
[ .. | to_entries[] | select(.value | type == "object" and has("description")) | .key ]
表达式拆解
我们一步步来看这个表达式是怎么工作的:
..:递归遍历JSON的所有节点,不管是顶级对象还是嵌套的子对象,都会被遍历到。to_entries[]:把每个遍历到的对象转换成键值对条目(比如{"normal": {"description": "NORMAL"}}会变成{"key":"normal", "value":{"description": "NORMAL"}}),然后展开成单个条目处理。select(.value | type == "object" and has("description")):筛选出那些值是对象,并且这个对象包含description键的条目。这一步就排除了simple(值是数字)和arbitrary(值是对象但没有description键)的情况。.key:提取符合条件的条目里的键,也就是我们需要的normal、one、two。- 外层的
[]:把所有提取到的键收集成一个数组,正好是你要的结果。
测试验证
用你提供的JSON输入:
{ "simple": 42, "normal": { "description": "NORMAL" }, "combo": { "one": { "description": "ONE" }, "two": { "description": "TWO" } }, "arbitrary": { "foo": 42 } }
运行上面的jq表达式,输出就是:
["normal","one","two"]
为什么之前的尝试可能没成功?
with_entries默认只处理顶级对象,不会递归遍历嵌套的子对象,所以拿不到one和two这些嵌套键。- 如果用
recurse,需要正确搭配to_entries来遍历所有层级的键值对,之前的写法可能没覆盖到这一步,导致漏了嵌套的情况。
内容的提问来源于stack exchange,提问作者Stephen Chu
相关产品推荐
相关产品推荐

