jq按指定键名搜索并返回第一个匹配标量值的问题求助
jq按指定键名搜索并返回第一个匹配标量值的问题求助
嘿,作为刚上手jq的新手,这种卡壳的感觉太熟悉了!我来帮你捋捋问题出在哪,以及怎么实现你要的递归搜索第一个匹配值的需求。
首先说你当前遇到的问题:你用map(.size)|.[0]?得到[null],是因为map只针对顶层对象的直接子元素操作——你的顶层JSON只有fruit这一个键,而fruit对象本身没有size属性,所以map返回了包含null的数组,这显然不是你要的递归全结构搜索效果。
下面给你两种符合需求的解决方案,分别对应深度优先和广度优先搜索:
深度优先搜索(jq默认遍历方式)
jq的..运算符可以递归遍历JSON的所有节点,我们可以利用它提取所有匹配键的值,过滤掉不存在的情况后取第一个结果:
比如找第一个name的值:
jq -r '.. | .name? // empty | first' your_json_file.json
输出结果:apple
找第一个size的值:
jq -r '.. | .size? // empty | first' your_json_file.json
输出结果:small
简单解释下命令逻辑:
..:递归遍历JSON的每一个节点(包括对象、数组、标量).name?:尝试提取当前节点的name属性,没有的话返回null// empty:把null替换为空值,自动过滤掉不存在目标键的情况first:取第一个非空的匹配结果
广度优先搜索
如果需要按「先顶层、再下一层、逐层深入」的顺序搜索,就需要自定义递归函数实现广度优先(因为..默认是深度优先):
jq -r ' def bfs($target_key): def recurse_level: ., (objects | .[] | recurse_level); recurse_level | objects | select(has($target_key)) | .[$target_key] | first; bfs("size") ' your_json_file.json
这个命令会优先检查顶层对象的所有直接子元素,再逐层往下搜索。在你的示例JSON里结果还是small,但如果是更复杂的嵌套结构,搜索顺序会和深度优先有明显区别。
这两种方法都不需要依赖JSON的固定结构,完全是按你指定的键名递归搜索第一个匹配的标量值,刚好符合你的需求。
备注:内容来源于stack exchange,提问作者symcbean
相关产品推荐
相关产品推荐

