我有一些需要使用 jq 解析的 json。我正在尝试提取 SecurityGroups>GroupId 如果任何 SecurityGroups>IpPermissions>IpRanges>CidrIp 匹配某个 IP。
例如,搜索 11.11.11.11 应该返回 sg-3jf32kj3j。有可能多个安全组将包含该 IP。我需要返回每个 GroupId。
这甚至可以单独使用 jq 还是需要 bash?
与仅使用 Python 之类的东西相比,我发现 jq 语法令人困惑。
{
"SecurityGroups": [{
"OwnerId": "111111111",
"Description": "default VPC security group",
"GroupId": "sg-1a1a1a1a1",
"VpcId": "vpc-1a1a1a1a1",
"IpPermissionsEgress": [{
"IpProtocol": "-1",
"PrefixListIds": [],
"Ipv6Ranges": [],
"UserIdGroupPairs": [],
"IpRanges": [{
"CidrIp": "0.0.0.0/0"
}]
}],
"GroupName": "default",
"IpPermissions": [{
"IpProtocol": "-1",
"PrefixListIds": [],
"Ipv6Ranges": [],
"UserIdGroupPairs": [{
"GroupId": "sg-5df45d5d5",
"UserId": "234234234"
}],
"IpRanges": []
}]
},
{
"OwnerId": "22222222222",
"Description": "EC2 Security Group",
"Tags": [{
"Key": "aws:cloudformation:logical-id",
"Value": "EC2SecurityGroup"
},
{
"Key": "aws:cloudformation:stack-id",
"Value": "arn:aws:cloudformation:us-west-2:111111111:stack/blah-prod-vpc/asdfsdf-j3j3-22j1-39fj-sadfsadf"
},
{
"Key": "Name",
"Value": "blah-production-EC2"
},
{
"Key": "Owner",
"Value": "blah@blah.com"
},
{
"Key": "aws:cloudformation:stack-name",
"Value": "prod-vpc"
},
{
"Key": "Created",
"Value": "2018-05-21T09:40:55-07:00"
}
],
"GroupId": "sg-3jf32kj3j",
"VpcId": "vpc-3kj3f2kj3",
"IpPermissionsEgress": [{
"IpProtocol": "-1",
"PrefixListIds": [],
"Ipv6Ranges": [],
"UserIdGroupPairs": [],
"IpRanges": [{
"CidrIp": "0.0.0.0/0"
}]
}],
"GroupName": "blah-prod-vpc-EC2SecurityGroup-SJHS78F78SSH",
"IpPermissions": [{
"IpProtocol": "tcp",
"ToPort": 80,
"UserIdGroupPairs": [],
"IpRanges": [{
"CidrIp": "0.0.0.0/0"
}],
"FromPort": 80,
"PrefixListIds": [],
"Ipv6Ranges": []
},
{
"IpProtocol": "icmp",
"ToPort": 0,
"UserIdGroupPairs": [],
"IpRanges": [{
"CidrIp": "11.11.11.11/32"
}],
"FromPort": 0,
"PrefixListIds": [],
"Ipv6Ranges": []
},
{
"IpProtocol": "-1",
"PrefixListIds": [],
"Ipv6Ranges": [],
"UserIdGroupPairs": [],
"IpRanges": [{
"CidrIp": "22.22.22.22/16"
},
{
"CidrIp": "33.33.33.33/32"
}
]
},
{
"IpProtocol": "tcp",
"ToPort": 22,
"UserIdGroupPairs": [],
"IpRanges": [{
"CidrIp": "0.0.0.0/0"
}],
"FromPort": 22,
"PrefixListIds": [],
"Ipv6Ranges": [{
"CidrIpv6": "::/0"
}]
},
{
"IpProtocol": "tcp",
"ToPort": 443,
"UserIdGroupPairs": [],
"IpRanges": [{
"CidrIp": "0.0.0.0/0"
}],
"FromPort": 443,
"PrefixListIds": [],
"Ipv6Ranges": []
},
{
"IpProtocol": "icmp",
"ToPort": -1,
"UserIdGroupPairs": [],
"IpRanges": [{
"CidrIp": "44.44.44.44/32"
},
{
"CidrIp": "55.55.55.55/29"
}
],
"FromPort": -1,
"PrefixListIds": [],
"Ipv6Ranges": []
}
]
}
]}
最佳答案
以下过滤器满足规定的要求:
.SecurityGroups[]
| select( any(.IpPermissions[].IpRanges[];
.CidrIp | startswith("11.11.11.11/") ) )
| .GroupId
特别是,根据您的输入,它会产生所需的值:
"sg-3jf32kj3j"
您可能想要考虑更复杂的模式匹配,也许使用:
test("^11.11.11.11($|/)")
如果要去掉引号,可以考虑使用jq的-r命令行选项。
使用..
这是另一个解决方案,但请注意它具有完全不同的语义:
..
| select( .. | test("^11.11.11.11($|/)")? )
| .GroupId? // empty
关于json - jq 迭代和条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54353243/