json - 使用 jq 通过匹配多个对象来过滤 JSON 对象列表

标签 json jq

我正在尝试过滤“aws elb describe-tags”的输出,并通过匹配三个标签来获取 LoadBalancerName。我不知道如何选择对象列表的特定元素并比较键和值。我要查看三个对象,如果它们全部匹配,我需要返回 LoadBalancerName。

以下是三个负载均衡器的输出示例,其中只有一个具有正确的标签集。

{
    "TagDescriptions": [
        {
            "Tags": [
                {
                    "Value": "production",
                    "Key": "environment"
                },
                {
                    "Value": "widget",
                    "Key": "service"
                },
                {
                    "Value": "widget_xyz",
                    "Key": "customer_prefix"
                },
                {
                    "Value": "widget_xyz-widget-production",
                    "Key": "Name"
                }
            ],
            "LoadBalancerName": "widget-xyz-widget-prod"
        },
        {
            "Tags": [
                {
                    "Value": "widget-xyz-stage-widget-ConsulStack-DKJSADKJS",
                    "Key": "aws:cloudformation:stack-name"
                },
                {
                    "Value": "stage",
                    "Key": "environment"
                },
                {
                    "Value": "arn:aws:cloudformation:us-east-1:123456789:stack/widget-xyz-stage-widget-ConsulStack-DKJSADKJS/d46ad520-92e7-11e5-a975-500150b34c7c",
                    "Key": "aws:cloudformation:stack-id"
                },
                {
                    "Value": "widget",
                    "Key": "service"
                },
                {
                    "Value": "widget_xyz",
                    "Key": "customer_prefix"
                },
                {
                    "Value": "ELB",
                    "Key": "aws:cloudformation:logical-id"
                },
                {
                    "Value": "widget_xyz-widget-stage",
                    "Key": "Name"
                }
            ],
            "LoadBalancerName": "widget-xyz-ELB-SDKJSDKJSADKJAS"
        },
        {
            "Tags": [
                {
                    "Value": "widget-xyz-prod-widget-ConsulStack-DLFJEIJNWDKD",
                    "Key": "aws:cloudformation:stack-name"
                },
                {
                    "Value": "prod",
                    "Key": "environment"
                },
                {
                    "Value": "arn:aws:cloudformation:us-east-1:123456789:stack/widget-xyz-prod-widget-ConsulStack-DLFJEIJNWDKD/ab2292f0-9398-11e5-b0f6-50d501114c2c",
                    "Key": "aws:cloudformation:stack-id"
                },
                {
                    "Value": "widget",
                    "Key": "service"
                },
                {
                    "Value": "widget_xyz",
                    "Key": "customer_prefix"
                },
                {
                    "Value": "ELB",
                    "Key": "aws:cloudformation:logical-id"
                },
                {
                    "Value": "widget_xyz-widget-prod",
                    "Key": "Name"
                }
            ],
            "LoadBalancerName": "widget-xyz-ELB-SKDJSKDJSAKDJAS"
        }
    ]
}

我已成功实现查询,但不安全。只要任何三个值与我的搜索模式匹配,它就会返回 LoadBalancerName。我想搜索特定的Key,然后比较Value。

这是我的不安全查询,它在要点上的片段上成功。它返回 widget-xyz-widget-prod,这是我想要获取的参数。

jq --raw-output '.TagDescriptions[] | select(.Tags[].Value=="widget_xyz") | select(.Tags[].Value=="小部件") | select(.Tags[].Value=="生产") | .LoadBalancerName'

如果所有三个条件都成立,它应该返回:

Key == "service" && Value == "widget"
Key == "environment" && Value == "production"
Key == "customer_prefix" && Value == "widget_xyz"

正如您在上面的查询中看到的,我只是比较值(value)。

更新:我已经能够构建一个查询来过滤匹配一个对象中的键和值,但我仍在尝试匹配多个对象。

.TagDescriptions[] | select(.Tags[].Key=="customer_prefix"和 .Tags[].Value =="widget_xyz") | .LoadBalancerName

另一个更新:好吧,我已经能够一起破解查询了。我感觉好像我仍然缺少一 block 拼图,并且可以使用 jq 的一些我尚未理解的巧妙功能来极大地简化此查询。

.TagDescriptions[] | [select(.Tags[].Key == "customer_prefix"and .Tags[].Value == "widget_xyz")][] | [select(.Tags[].Key == "环境"and .Tags[].Value == "生产")][] | [select(.Tags[].Key == "service"and .Tags[].Value == "widget")][] | .LoadBalancerName

最佳答案

Tags 数组非常适合创建易于访问的对象。让事情变得简单,然后就这样做。那么获取这些值就会变得更加容易。然后您就可以轻松测试看看您的条件是否满足。

.TagDescriptions[] | select(
    .Tags | from_entries | [
        .service == "widget",
        .environment == "production",
        .customer_prefix == "widget_xyz"
    ] | all
).LoadBalancerName

关于json - 使用 jq 通过匹配多个对象来过滤 JSON 对象列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33973816/

相关文章:

java - 什么是用于在 JSON 对象数组中选择字段值的 Rest Assured 正确 JsonPath get() 格式

javascript - 如何按特定顺序正确收集json数据

json - 从 JSON 文件中删除换行符、制表符和回车符等转义序列字符

json - 使用JQ(YQ)添加/删除k8s入口 list 中的后端 block

json - JMESPath 从对象的对象生成对象数组

json - JQ转换为数字,从shell变量生成新的json时转换为boolean

json - jq - 如何过滤不包含的json

java - 如何在Java中的RESTful(WEB SERVICE)POST方法中接收json对象

javascript - php 数组中转换 json 字符串时出现问题

javascript - 纠正格式错误的 JSON 数据