Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

filter json via bash - case insensitive

I have json code and need to filter it by the value of the attribute DNSName. The filter must be case insensitive.

How can I do that? Is there a possibility to solve it with jq?

This is how I create the json code:

aws elbv2 describe-load-balancers --region=us-west-2 | jq

My unfiltered source json code looks like this:

{
    "LoadBalancers": [
        {
            "IpAddressType": "ipv4", 
            "VpcId": "vpc-abcdabcd", 
            "LoadBalancerArn": "arn:aws:elasticloadbalancing:us-west-2:000000000000:loadbalancer/app/MY-LB1/a00000000000000a", 
            "State": {
                "Code": "active"
            }, 
            "DNSName": "MY-LB1-123454321.us-west-2.elb.amazonaws.com", 
            "SecurityGroups": [
                "sg-00100100", 
                "sg-01001000", 
                "sg-10010001"
            ], 
            "LoadBalancerName": "MY-LB1", 
            "CreatedTime": "2018-01-01T00:00:00.000Z", 
            "Scheme": "internet-facing", 
            "Type": "application", 
            "CanonicalHostedZoneId": "ZZZZZZZZZZZZZ", 
            "AvailabilityZones": [
                {
                    "SubnetId": "subnet-17171717", 
                    "ZoneName": "us-west-2a"
                }, 
                {
                    "SubnetId": "subnet-27272727", 
                    "ZoneName": "us-west-2c"
                }, 
                {
                    "SubnetId": "subnet-37373737", 
                    "ZoneName": "us-west-2b"
                }
            ]
        }, 
        {
            "IpAddressType": "ipv4", 
            "VpcId": "vpc-abcdabcd", 
            "LoadBalancerArn": "arn:aws:elasticloadbalancing:us-west-2:000000000000:loadbalancer/app/MY-LB2/b00000000000000b", 
            "State": {
                "Code": "active"
            }, 
            "DNSName": "MY-LB2-9876556789.us-west-2.elb.amazonaws.com", 
            "SecurityGroups": [
                "sg-88818881"
            ], 
            "LoadBalancerName": "MY-LB2", 
            "CreatedTime": "2018-01-01T00:00:00.000Z", 
            "Scheme": "internet-facing", 
            "Type": "application", 
            "CanonicalHostedZoneId": "ZZZZZZZZZZZZZ", 
            "AvailabilityZones": [
                {
                    "SubnetId": "subnet-54545454", 
                    "ZoneName": "us-west-2a"
                }, 
                {
                    "SubnetId": "subnet-64646464", 
                    "ZoneName": "us-west-2c"
                }, 
                {
                    "SubnetId": "subnet-74747474", 
                    "ZoneName": "us-west-2b"
                }
            ]
        }
    ]
}

I now want some bash code to filter this result for the record with the DNSName property value MY-LB2-9876556789.us-west-2.elb.amazonaws.com, and need the entire LoadBalancer object back as a result. This is how I wish my result to look like:

{
    "IpAddressType": "ipv4", 
    "VpcId": "vpc-abcdabcd", 
    "LoadBalancerArn": "arn:aws:elasticloadbalancing:us-west-2:000000000000:loadbalancer/app/MY-LB2/b00000000000000b", 
    "State": {
        "Code": "active"
    }, 
    "DNSName": "MY-LB2-9876556789.us-west-2.elb.amazonaws.com", 
    "SecurityGroups": [
        "sg-88818881"
    ], 
    "LoadBalancerName": "MY-LB2", 
    "CreatedTime": "2018-01-01T00:00:00.000Z", 
    "Scheme": "internet-facing", 
    "Type": "application", 
    "CanonicalHostedZoneId": "ZZZZZZZZZZZZZ", 
    "AvailabilityZones": [
        {
            "SubnetId": "subnet-54545454", 
            "ZoneName": "us-west-2a"
        }, 
        {
            "SubnetId": "subnet-64646464", 
            "ZoneName": "us-west-2c"
        }, 
        {
            "SubnetId": "subnet-74747474", 
            "ZoneName": "us-west-2b"
        }
    ]
}

Does anyone know how to do it?


Update: This solution works, but is not case insensitive:

aws elbv2 describe-load-balancers --region=us-west-2 | jq -c '.LoadBalancers[] | select(.DNSName | contains("MY-LB2"))'

Update: This solution seems to work even better:

aws elbv2 describe-load-balancers --region=us-west-2 | jq -c '.LoadBalancers[] | select(.DNSName | match("my-lb2";"i"))'

But I did not have the chance to test in detail yet.

like image 484
hey Avatar asked Aug 07 '18 02:08

hey


1 Answers

You probably should be using test/2 rather than match/2, but in either case, since the problem description calls for case-insensitive equality, you would use an anchored regex:

.LoadBalancers[]
| select(.DNSName | test("^my-lb2-9876556789.us-west-2.elb.amazonaws.com$";"i"))

With the caveat that ascii_upcase only translates ASCII characters, it might be more efficient to use it:

 .LoadBalancers[]
 | select(.DNSName | ascii_upcase == "MY-LB2-9876556789.US-WEST-2.ELB.AMAZONAWS.COM")
like image 168
peak Avatar answered Oct 12 '22 07:10

peak