user6127511
user6127511

Reputation: 307

jq - Iterate over objects in bash like an array (aws volumes)

I have some JSON that I have pulled from AWS and formatted with jq (the original code is at the bottom) to give me the following output:

{
  "VolumeId": "vol-11111111",
  "Tags": {
    "Name": "volume1",
    "Finish": "00:00",
    "Start": "00:20",
    "Period": "2"
  }
}
{
  "VolumeId": "vol-22222222",
  "Tags": {
    "Name": "volume2",
    "Period": "1",
    "Start": "00:00",
    "Finish": "00:20"
  }
}
{
  "VolumeId": "vol-33333333",
  "Tags": {
    "Period": "1",
    "Start": "00:00",
    "Name": "volume3",
    "Finish": "00:20"
  }
}

What I now need to do is to pull the 'VolumeId', 'Period', 'Start' and 'Finish'. I would like to iterate over these objects put these into 4 bash variables of the same name in a for loop.

e.g.

VolumeId="vol-33333333"
Period="1"
Start="00:00"
Finish="00:20"

The problem is that if I put the entire JSON into a variable, it is treated as a single argument. I could use something like mapfile, however it would then turn it into too many arguments - e.g.

}
"Volumes": [
{ 

etc

Any help in getting this to work would be greatly appreciated. The end result is to be able to take a snapshot of the volume and use the 'Period' tag to calculate retention etc.

-- Original JSON:

{
"Volumes": [
    {
        "Attachments": [],
        "Tags": [
            {
                "Value": "volume1",
                "Key": "Name"
            },
            {
                "Value": "00:00",
                "Key": "Start"
            },
            {
                "Value": "00:20",
                "Key": "Finish"
            },
            {
                "Value": "2",
                "Key": "Period"
            }
        ],
        "VolumeId": "vol-11111111"
    },
    {
        "Attachments": [],
        "Tags": [
            {
                "Value": "volume2",
                "Key": "Name"
            },
            {
                "Value": "00:00",
                "Key": "Start"
            },
            {
                "Value": "00:20",
                "Key": "Finish"
            },
            {
                "Value": "2",
                "Key": "Period"
            }
        ],
        "VolumeId": "vol-22222222"
    },
    {
        "Attachments": [],
        "Tags": [
            {
                "Value": "volume3",
                "Key": "Name"
            },
            {
                "Value": "00:00",
                "Key": "Start"
            },
            {
                "Value": "00:20",
                "Key": "Finish"
            },
            {
                "Value": "2",
                "Key": "Period"
            }
        ],
        "VolumeId": "vol-33333333"
    }
]
}

and the jq command:

jq -r '.Volumes[] | {"VolumeId": .VolumeId, "Tags": [.Tags[]] | from_entries}' 

Upvotes: 3

Views: 4860

Answers (1)

tink
tink

Reputation: 153

cat rawjsonfile |jq -r  '.Volumes[]|({VolumeId}+(.Tags|from_entries))|{VolumeId,Period,Start,Finish}|to_entries[]|(.key+"="+.value)'

the rawjsonfile is your "-- Original JSON"

this result is:

VolumeId=vol-11111111
Period=2
Start=00:00
Finish=00:20
VolumeId=vol-22222222
Period=2
Start=00:00
Finish=00:20
VolumeId=vol-33333333
Period=2
Start=00:00
Finish=00:20
  1. first unwind the array to json units

cat rawjsonfile|jq -r '.Volumes[]|({VolumeId}+(.Tags|from_entries))'

the result of first step like this:

 {
  "VolumeId": "vol-11111111",
  "Name": "volume1",
  "Start": "00:00",
  "Finish": "00:20",
  "Period": "2"
}
{
  "VolumeId": "vol-22222222",
  "Name": "volume2",
  "Start": "00:00",
  "Finish": "00:20",
  "Period": "2"
}
{
  "VolumeId": "vol-33333333",
  "Name": "volume3",
  "Start": "00:00",
  "Finish": "00:20",
  "Period": "2"
}

jq support join the json object .

  1. second choose the fields

|{VolumeId,Period,Start,Finish}

3.make it to key-value and join them

|to_entries[]|(.key+"="+.value)

Upvotes: 4

Related Questions