Using jq to select a parent by searching for a pair of child keys / values

Using jq , how to select a parent if it contains a child that meets two filter requirements?

In this example, I want to highlight all Subnets that have a child tag with the key "Name" and the value "TheName". My example consists of two subnets. The first has "TheName" in the wrong way. The second subnet has the name / value pair that I am looking for. those. "Key": "Name", "Value": "TheName"

Next, select the subnet with the specified value in one of the tags, but not in pairs. It returns both subnets instead of the second subnet.

 jq '.Subnets[] | select(.Tags[].Value=="TheName")' output 

How to use jq to select only subnets that have the name / value pair I'm looking for?

 { "Subnets": [ { "VpcId": "vpc-12345678", "SubnetId": "subnet-1234567a", "Tags": [ { "Key": "IgnoreThis", "Value": "TheName" }, { "Key": "Name", "Value": "NotTheName" } ] }, { "VpcId": "vpc-12345678", "SubnetId": "subnet-1234567b", "Tags": [ { "Key": "IgnoreThis", "Value": "ignore" }, { "Key": "Name", "Value": "TheName" } ] } ] } 

Desired Result:

 { "VpcId": "vpc-12345678", "SubnetId": "subnet-1234567b", "Tags": [ { "Key": "IgnoreThis", "Value": "ignore" }, { "Key": "Name", "Value": "TheName" } ] } 
+5
source share
2 answers

Assuming your jq has any/2 , a simple and effective solution would be the following:

 .Subnets[] | select( any (.Tags[]; .Key == "Name" and .Value == "TheName") ) 

This will lead to the output you want, so I will not repeat it here.

If your jq does not have any/2 , I would suggest an update, but if it is inconvenient or not, you can use this def:

 def any(f;g): reduce f as $i (false; . or ($i|g)); 

ps any(str; cond) can be read like: "Is there any element e in the str stream such that e|cond has a value other than null or false ? '

+4
source

Here is a solution that uses indices

 .Subnets[] | select(.Tags | indices({Key:"Name", Value:"TheName"}) != []) 
0
source

Source: https://habr.com/ru/post/1258006/


All Articles