Reputation: 35
I am trying to get a value from an array by matching a value in a child array, but everything I try either returns nothing or all of members of the parent array. I only want the info from the parent where the child matches.
Specifically, I want to list all of the AWS security groups that have port 22 rules in them.
This is a reduced sample output from the aws command line that I am trying to parse:
{
"SecurityGroups": [
{
"Description": "ssh and web group",
"IpPermissions": [
{
"FromPort": 22,
"ToPort": 22
},
{
"FromPort": 80,
"ToPort": 80
}
],
"GroupName": "ssh-web",
"GroupId": "sg-11111111"
},
{
"Description": "https group",
"IpPermissions": [
{
"FromPort": 443,
"ToPort": 443
},
{
"FromPort": 8443,
"ToPort": 8443
}
],
"GroupName": "https",
"GroupId": "sg-22222222"
}
]
}
I have tried this:
aws ec2 describe-security-groups |
jq '.SecurityGroups[] as $top |
.SecurityGroups[].IpPermissions[] |
select(.FromPort == 22) |
$top'
and this:
aws ec2 describe-security-groups |
jq '. as $top |
.SecurityGroups[].IpPermissions[] |
select(.FromPort == 22) |
$top'
Both commands show both of the top-level array entries instead of just one containing the port 22 entry; they just show the entire output from the aws command.
The person who answered this question below specifically refers to the potential scoping problem that I am actually having, but his brief description of how to deal with it isn't enough for me to understand:
jq - How do I print a parent value of an object when I am already deep into the object's children?
I want to see this:
GroupName: "https"
GroupID: "sg-22222222"
I don't think I fully understand how using 'as' works, which may be my stumbling block.
Upvotes: 1
Views: 258
Reputation: 50750
Don't descend into children if you need parent.
.SecurityGroups[]
| select(any(.IpPermissions[]; .FromPort == 22))
| .GroupName, .GroupId
should work.
Upvotes: 3