DarkForce
DarkForce

Reputation: 101

How to filter JSON data with jq based on values from multiple keys and show one particular attribute if the filter succeeds?

For example, I have this JSON data:

{
    "Instances": [
        {
            "Monitoring": {
                "State": "disabled"
            }, 
            "PublicDnsName": "ec2-aa.compute-1.amazonaws.com", 
            "State": {
                "Code": 16, 
                "Name": "running"
            }, 
            "EbsOptimized": false, 
            "LaunchTime": "2017-08-14T17:29:54.000Z", 
            "PublicIpAddress": "aa", 
            "PrivateIpAddress": "bb", 
            "ProductCodes": [], 
            "VpcId": "vpc-xx", 
            "StateTransitionReason": "", 
            "InstanceId": "i-f21c76a0", 
            "ImageId": "ami-xx", 
            "PrivateDnsName": "ip-bb.ec2.internal", 
            "KeyName": "blah", 
            "SecurityGroups": [
                {
                    "GroupName": "mygroup", 
                    "GroupId": "sg-xx"
                }
            ], 
            "ClientToken": "", 
            "SubnetId": "subnet-xx", 
            "InstanceType": "t2.micro", 
            "NetworkInterfaces": [
                {
                    "Status": "in-use", 
                    "MacAddress": "", 
                    "SourceDestCheck": true, 
                    "VpcId": "vpc-xx", 
                    "Description": "", 
                    "NetworkInterfaceId": "eni-xx", 
                    "PrivateIpAddresses": [
                        {
                            "PrivateDnsName": "ip-bb.ec2.internal", 
                            "PrivateIpAddress": "aa", 
                            "Primary": true, 
                            "Association": {
                                "PublicIp": "aa", 
                                "PublicDnsName": "ec2-bb-1.amazonaws.com", 
                                "IpOwnerId": "amazon"
                            }
                        }
                    ], 
                    "PrivateDnsName": "ip-aa.ec2.internal", 
                    "Attachment": {
                        "Status": "attached", 
                        "DeviceIndex": 0, 
                        "DeleteOnTermination": true, 
                        "AttachmentId": "eni-attach-b11454cb", 
                        "AttachTime": "2014-07-02T19:24:19.000Z"
                    }, 
                    "Groups": [
                        {
                            "GroupName": "mygroup", 
                            "GroupId": "sg-xx"
                        }
                    ], 
                    "Ipv6Addresses": [], 
                    "OwnerId": "aa", 
                    "PrivateIpAddress": "aa", 
                    "SubnetId": "subnet-bb", 
                    "Association": {
                        "PublicIp": "aa", 
                        "PublicDnsName": "ec2-aa-1.amazonaws.com", 
                        "IpOwnerId": "amazon"
                    }
                }
            ], 
            "SourceDestCheck": true, 
            "Placement": {
                "Tenancy": "default", 
                "GroupName": "", 
                "AvailabilityZone": "us-east-1e"
            }, 
            "Hypervisor": "xen", 
            "BlockDeviceMappings": [
                {
                    "DeviceName": "/dev/sda1", 
                    "Ebs": {
                        "Status": "attached", 
                        "DeleteOnTermination": true, 
                        "VolumeId": "vol-4fb6ed03", 
                        "AttachTime": "2014-07-02T19:24:23.000Z"
                    }
                }
            ], 
            "Architecture": "x86_64", 
            "RootDeviceType": "ebs", 
            "RootDeviceName": "/dev/sda1", 
            "VirtualizationType": "hvm", 
            "Tags": [
                {
                    "Value": "qa", 
                    "Key": "environment"
                }, 
                {
                    "Value": "database", 
                    "Key": "system"
                }, 
                {
                    "Value": "databaseteam", 
                    "Key": "team"
                }
            ], 
            "AmiLaunchIndex": 0
        }
    ], 
    "ReservationId": "r-xx", 
    "Groups": [], 
    "OwnerId": "xx"
}

Similar data is scattered throughout the JSON data as obtained from aws ec2 describe-instances command.

Now I want to filter PrivateIPAddress and InstanceType only if some key: value pair from the Tags[] array match. I am primarily looking for something like, if select(.Value == "qa" and .Value == databaseteam) match. In other words, based out of match criterion from the Tags array defined in the jq filter, I want to show PrivateIPAddress and InstanceType.

How I can achieve this? I have tried map, select and possibly all kinds of previous SO answers, github issue replies but I can't get this to work.

Thanks,

Upvotes: 0

Views: 697

Answers (1)

peak
peak

Reputation: 116870

The question is a bit confusing; for example, it seems to presuppose that .Value can simultaneously be equal to both "qa" and "databaseteam". In fact, in your sample data, there is no "instance" for which(.Value == "qa" and .Key == "databaseteam") either, so for the sake of this illustration, I'll assume you meant

select(.Value == "qa" and .Key == "environment")

However, if you meant something else, perhaps select(.Value == "qa" or .Value == "databaseteam"), you can easily adapt the following, which produces the results shown below.

.Instances[]
| .PrivateIpAddress as $PIPA
| .InstanceType as $IT
| .Tags[]
| select(.Value == "qa" and .Key == "environment")
| [$PIPA, $IT]

Transcript

$ jq -f program.jq data.json
[
  "bb",
  "t2.micro"
]

Upvotes: 1

Related Questions