AWS CLI 和 JMESPath 过滤器以及嵌套属性上的 select

AWS CLI and JMESPath filter and select on nested properties

我想使用 CLI 工具来检索具有特定 cname/alias 的 CloudFront 分配的分配 ID。

这是我想出的:

aws cloudfront list-distributions --query "DistributionList.Items[?Aliases.Items!='null']|DistributionList.Items[?contains(Aliases.Items,'cname.cdn.mycompany.com') == 'true'].{Id:Id}"

我不是 JMESPath 方面的专家,我不明白为什么我的查询没有 return 结果。存在以指定域作为别名的分发。

你非常接近!不过有几点:

  • null 不是 'null'
  • 在管道之后,您将使用第一个表达式的结果
  • null一样,true不是字符串(== true也是多余的)

jmespath.org 有一个可以用来测试表达式的实时编辑器。这是我们可以用来测试这种情况的简化 json:

{
    "DistributionList": {
        "Items": [
            {
                "Id": "foo",
                "Aliases": {
                    "Quantity": 1,
                    "Items": [
                        "cname.cdn.mycompany.com"
                    ]
                }
            },
            {
                "Id": "bar",
                "Aliases": {
                    "Quantity": 1,
                    "Items": [
                        "cname.cdn.othercompany.com"
                    ]
                }
            },
            {
                "Id": "baz",
                "Aliases": {
                    "Quantity": 0
                }
            }
        ]
    }
}

让我们从表达式的第一部分开始。您唯一需要解决的问题是取消引号 null:

DistributionList.Items[?Aliases.Items!=null]

将成功过滤掉Alias下没有Items的元素。如果你在这里停下来,你会得到什么,以及你在管道之后必须处理的事情:

[
  {
    "Id": "foo",
    "Aliases": {
      "Quantity": 1,
      "Items": [
        "cname.cdn.mycompany.com"
      ]
    }
  },
  {
    "Id": "bar",
    "Aliases": {
      "Quantity": 1,
      "Items": [
        "cname.cdn.othercompany.com"
      ]
    }
  }
]

请注意,不再有 DistributionList.Items

所以现在我们要过滤特定的 CNAME。让我们省略重言式 == true.

[?contains(Aliases.Items, 'cname.cdn.mycompany.com')]

所以现在的完整表达式是:

DistributionList.Items[?Aliases.Items!=null] | [?contains(Aliases.Items, 'cname.cdn.mycompany.com')]

你的结果是过滤成功的列表:

[
  {
    "Id": "foo",
    "Aliases": {
      "Quantity": 1,
      "Items": [
        "cname.cdn.mycompany.com"
      ]
    }
  }
]

现在,如果您需要匹配元素的 ID,只需将 .Id 添加到最后一个表达式即可。如果你知道只有一个,你可以 select 用另一个管道和 [0].

那个元素
DistributionList.Items[?Aliases.Items!=null] | [?contains(Aliases.Items, 'cname.cdn.mycompany.com')].Id | [0]

你得到了你想要的ID!

"foo"

补充一下,没管子的我发现了

aws cloudfront list-distributions --query "DistributionList.Items[?contains(Aliases.Items, 'cname.cdn.mycompany.com')].Id" --output text