user3255401
user3255401

Reputation: 135

retrieve multiple values from json array using bash

I need to write a bash script to attach Amazon EBS volumes to a given instance based on the Name tag of the volume. The tag is in the format of "device on servername" e.g. "/dev/xvdf on linuxserver"

I can easily perform the following command to retrieve all the relevant instances, but I am having trouble iterating through each object in the json array to get VolumeId and Name tag.

aws ec2 describe-volumes --region $region --filter Name=tag-key,Values="Name" Name=tag-value,Values="*$servername" --filter Name="status",Values="available" | jq '.Volumes[]'

an example output is:

 [
  {
    "AvailabilityZone": "us-east-1d",
    "Attachments": [],
    "Tags": [
      {
        "Value": "/dev/xvdg on linuxserver",
        "Key": "Name"
      }
    ],
    "Encrypted": false,
    "VolumeType": "io1",
    "VolumeId": "vol-0233d8ec",
    "State": "available",
    "Iops": 120,
    "SnapshotId": "",
    "CreateTime": "2015-08-21T04:29:10.157Z",
    "Size": 4
  },
  {
    "AvailabilityZone": "us-east-1d",
    "Attachments": [],
    "Tags": [
      {
        "Value": "/dev/xvdf on linuxserver",
        "Key": "Name"
      }
    ],
    "Encrypted": false,
    "VolumeType": "io1",
    "VolumeId": "vol-433bc8ae",
    "State": "available",
    "Iops": 120,
    "SnapshotId": "",
    "CreateTime": "2015-08-21T04:28:23.819Z",
    "Size": 4
  }
]

Ideally, I'd like to do the following:

for object in $(aws ec2 describe-volumes --region $region --filter Name=tag-key,Values="Name" Name=tag-value,Values="*$servername" --filter Name="status",Values="available" | jq '.Volumes[]')
do
    echo $object.VolumeId
done 

But bash treats each line as an object in the array.

I'd be very appreciative of some suggestions on a better way to approach this.

Thanks

Upvotes: 3

Views: 1646

Answers (1)

scrowler
scrowler

Reputation: 24405

The jq package might help you here. It was created to fill the void of ability to parse JSON with bash scripts.

An example for how to get the volume IDs from your sample data:

aws ec2 describe-volumes --region $region --filter Name=tag-key,Values="Name"\
    Name=tag-value,Values="*$servername" --filter Name="status",Values="available"\
    | jq .[].VolumeId

Output:

"vol-0233d8ec"
"vol-433bc8ae"

You could split it to iterate over it as an array like so:

#!/bin/bash

volumeIds=$(aws ec2 describe-volumes --region $region --filter Name=tag-key,Values="Name"\
    Name=tag-value,Values="*$servername" --filter Name="status",Values="available"\
    | jq .[].VolumeId)

for i in `echo "$volumeIds"`
do
  echo "$i is a volume ID"
done

# "vol-0233d8ec" is a volume ID
# "vol-433bc8ae" is a volume ID

Upvotes: 1

Related Questions