从 JQ 中复杂的嵌套 JSON 数据中进行选择

Ale*_*vey 2 json any jq

我有这样的 JSON 数据:

{
  "profiles": {
    "auto_scaler": [
      {
        "auto_scaler_group_name": "myasg0",
        "auto_scaler_group_options": {
          ":availability_zones": ["1a", "1b", "1c"],
          ":max_size": 1,
          ":min_size": 1,
          ":subnets": ["a", "b", "c"],
          ":tags": [
            {":key": "Name", ":value": "app0" },
            {":key": "env", ":value": "dev" },
            {":key": "role", ":value": "app" },
            {":key": "domain", ":value": "example.com" },
            {":key": "fonzi_app", ":value": "true"},
            {":key": "vpc", ":value": "nonprod"}
          ]
        },
        "dns_name": "fonz1"
      },
      {
        "auto_scaler_group_name": "myasg1",
        "auto_scaler_group_options": {
          ":availability_zones": ["1a", "1b", "1c"],
          ":max_size": 1,
          ":min_size": 1,
          ":subnets": ["a", "b", "c"],
          ":tags": [
            {":key": "Name", ":value": "app1" },
            {":key": "env", ":value": "dev" },
            {":key": "role", ":value": "app" },
            {":key": "domain", ":value": "example.com" },
            {":key": "bozo_app", ":value": "true"},
            {":key": "vpc", ":value": "nonprod"}
          ]
        },
        "dns_name": "bozo1"
      }
    ]
  }
}
Run Code Online (Sandbox Code Playgroud)

我想编写一个 jq 查询来首先选择 Array 中的 Hash 元素,.profiles.auto_scaler其 Array of Hashes at.auto_scaler_group_options.tags包含 Hashes 包含一个 " :key" 键,其值包含" fonzi" 和一个 " :value" 键,其值恰好是 true,然后返回关键dns_name

在示例中,查询将简单地返回 "fonz1"

有没有人知道如何做到这一点,如果可能的话,使用 jq?

pea*_*eak 5

简而言之,是的。

长:

.profiles.auto_scaler[]
| .dns_name as $name
| .auto_scaler_group_options
| select( any(.[":tags"][];
             (.[":key"] | index("fonzi")) and (.[":value"] == "true")) )
| $name
Run Code Online (Sandbox Code Playgroud)

上面的输出是:

"fonz1"
Run Code Online (Sandbox Code Playgroud)

这里的技巧是在更深入地研究“复杂的嵌套 JSON”之前提取候选 .dns_name。

替代

如果您的 jq 没有any,您可以(在这种特殊情况下)通过将select上面的表达式替换为:

 select( .[":tags"][]
         | (.[":key"] | index("fonzi")) and (.[":value"] == "true") )
Run Code Online (Sandbox Code Playgroud)

但是请注意,这两个表达式的语义略有不同。(作业练习:有什么区别?)

如果您的 jq 没有any,并且您想要 的语义any,那么您可以轻松推出自己的,或者只是升级:-)