Amazon web services 使用jq在select中捕获值并在顶级对象中使用它
根据aws ec2的响应,描述子网,如下所示: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,
{
"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文档提供了这种命令的基本用法。