使用jq以递归方式选择对象的键名

时间:2018-03-28 18:25:53

标签: json recursion key yaml jq

我有一个类似的JSON文档:

simple: 42

normal:
  description: "NORMAL"

combo:
  one:
    description: "ONE"
  two:
    description: "TWO"
  arbitrary:
    foo: 42

我想使用jq表达式生成以下内容:

["normal", "one", "two"]

选择密钥的条件是其对应的值是具有密钥object的{​​{1}}类型。在这种情况下,密钥descriptionsimple不符合条件。

我很难制作滤镜。查看arbitrarywith_entries但无法自行解决。

TIA。

1 个答案:

答案 0 :(得分:1)

我不清楚你提供的YAML是否只是你对JSON的“视图”,或者你是否真的想从YAML开始。如果您的文档确实是YAML,那么一种方法是使用工具 (例如yaml2json或yq)将yaml转换为JSON,然后运行jq 如下所示;另一种方法是使用jq作为文本处理器, 但在这种情况下你也可以使用awk。

yaml2json input.yaml |
  jq -c '[.. | objects | to_entries[] 
          | select(.value | has("description")?) | .key]'

输出

["normal","one","two"]

流式解析器

这类问题也非常适合jq的流解析器,在处理非常大的JSON文本时尤其方便。使用jq --stream,合适的jq过滤器将是:

[select(length==2) | .[0] | select(.[-1] == "description") | .[-2]] 

结果的排序取决于YAML-to-JSON转换工具生成的密钥的顺序。