Amazon web services 使用jq在select中捕获值并在顶级对象中使用它

Amazon web services 使用jq在select中捕获值并在顶级对象中使用它,amazon-web-services,jq,aws-cli,Amazon Web Services,Jq,Aws Cli,根据aws ec2的响应,描述子网,如下所示: { "Subnets": [ { "AvailabilityZone": "us-west-2b", "AvailabilityZoneId": "usw2-az2", "AvailableIpAddressCount": 8187,

根据aws ec2的响应,描述子网,如下所示:

{
    "Subnets": [
        {
            "AvailabilityZone": "us-west-2b",
            "AvailabilityZoneId": "usw2-az2",
            "AvailableIpAddressCount": 8187,
            "CidrBlock": "10.0.96.0/19",
            "DefaultForAz": false,
            "MapPublicIpOnLaunch": false,
            "State": "available",
            "SubnetId": "subnet-08000000000000000",
            "VpcId": "vpc-06ba0000000000000",
            "OwnerId": "350000000000",
            "AssignIpv6AddressOnCreation": false,
            "Ipv6CidrBlockAssociationSet": [],
            "Tags": [
                {
                    "Key": "aws:cloudformation:logical-id",
                    "Value": "PrivateSubnet02"
                },
                {
                    "Key": "aws:cloudformation:stack-name",
                    "Value": "dev"
                },
                {
                    "Key": "Name",
                    "Value": "Private Subnet2"
                }
            ],
            "SubnetArn": "arn:aws:ec2:us-west-2:350000000000:subnet/subnet-08000000000000000"
        }
    ],
    "NextToken": "eyJOZXh0VG9r=="
}

我想生成一个JSON对象,其中包含Name标记的值以及子网ID,如果名称与某个字符串匹配,例如testing。这是我最初的尝试:

aws ec2 describe-subnets | jq '
.Subnets[] 
| select(
    .Tags[]? 
    | select(.Key == "Name") 
    | .Value as $name 
    | .Value 
    | test("testing")) 
| {"Name": $name, "SubnetId": .SubnetId}'

这将导致错误消息:

jq: error: name/0 is not defined at <top-level>, line 9:
| {"Name": $name, "SubnetId": .SubnetId}           
jq: 1 compile error

问题是,我试图在$name变量超出范围时使用它,但我不知道如何提前定义$name变量


捕获名称标记值的最佳方法是什么?我们碰巧知道只有一个名称标记实例,如果没有,则可以执行类似于1的操作。选择第一个实例,2。选择最后一个实例,或3。出错。

我找到了一个有效的解决方案:

aws ec2 describe-subnets | jq '
.Subnets[]
| select(
    .Tags[]?
    | select(.Key == "Name")
    | .Value
    | test("testing"))
| . as $obj
| .Tags[]
| select(.Key == "Name")
| .Value as $name
| {"Name": $name, "SubnetId": $obj.SubnetId}'

返回:

{
  "Name": "testing-vpc-stack-Subnet02",
  "SubnetId": "subnet-02000000000000000"
}
{
  "Name": "testing-vpc-stack-Subnet01",
  "SubnetId": "subnet-06900000000000000"
}
{
  "Name": "testing-vpc-stack-Subnet03",
  "SubnetId": "subnet-09b00000000000000"
}


但我很好奇是否还有其他选择。

我找到了一个可行的解决方案:

aws ec2 describe-subnets | jq '
.Subnets[]
| select(
    .Tags[]?
    | select(.Key == "Name")
    | .Value
    | test("testing"))
| . as $obj
| .Tags[]
| select(.Key == "Name")
| .Value as $name
| {"Name": $name, "SubnetId": $obj.SubnetId}'

返回:

{
  "Name": "testing-vpc-stack-Subnet02",
  "SubnetId": "subnet-02000000000000000"
}
{
  "Name": "testing-vpc-stack-Subnet01",
  "SubnetId": "subnet-06900000000000000"
}
{
  "Name": "testing-vpc-stack-Subnet03",
  "SubnetId": "subnet-09b00000000000000"
}

但我很好奇是否还有其他选择。

试试看

jq  '.Subnets[]|
    { "Name": ( .Tags|from_entries| .Name), "SubnetID": .SubnetID} |
    select(.Name | test("testing"))'
试一试


您可以尝试下面的命令,该命令不使用JQ进行解析,完全基于aws cli查询

aws ec2 describe-subnets --query 'Subnets[*].{Subnet_ID:SubnetId,Name:Tags[?Key==`Name`].Value|[0]}'  --output json
查询的输出

    {
        "Subnet_ID": "subnet-abcd",
        "Name": "Staging-2a"
    }

您可以尝试下面的命令,该命令不使用JQ进行解析,完全基于aws cli查询

aws ec2 describe-subnets --query 'Subnets[*].{Subnet_ID:SubnetId,Name:Tags[?Key==`Name`].Value|[0]}'  --output json
查询的输出

    {
        "Subnet_ID": "subnet-abcd",
        "Name": "Staging-2a"
    }

是的,很少需要使用JQ。AWS CLI-query参数使用并非常强大。请看:@JohnRotenstein是的,没错,但我认为人们喜欢JQ的一个原因可能是它的文档,因为AWS文档提供了这种命令的基本用法。是的,很少需要使用JQ。AWS CLI-query参数使用并非常强大。请看:@JohnRotenstein确实如此,但我认为人们选择JQ的一个原因可能是它的文档,因为AWS文档提供了这种命令的基本用法。