3

I have some JSON. It looks like this:

{
"Volumes": [
    {
        "Attachments": [
            {
                "VolumeId": "vol-11111111",
                "State": "attached",
                "DeleteOnTermination": false,
                "Device": "/dev/sdz"
            }
        ],
        "Tags": [
            {
                "Value": "volume1",
                "Key": "Name"
            },
            {
                "Value": "00:00",
                "Key": "Start"
            },
            {
                "Value": "00:20",
                "Key": "Finish"
            },
            {
                "Value": "2",
                "Key": "Period"
            }
        ],
        "VolumeId": "vol-11111111"
    },
    {
        "Attachments": [
            {
                "VolumeId": "vol-22222222",
                "State": "attached",
                "DeleteOnTermination": false,
                "Device": "/dev/sdz"
            }
        ],
        "Tags": [
            {
                "Value": "volume2",
                "Key": "Name"
            },
            {
                "Value": "00:00",
                "Key": "Start"
            },
            {
                "Value": "00:20",
                "Key": "Finish"
            },
            {
                "Value": "2",
                "Key": "Period"
            }
        ],
        "VolumeId": "vol-22222222"
    },
    {
        "Attachments": [
            {
                "VolumeId": "vol-333333333",
                "State": "attached",
                "DeleteOnTermination": false,
                "Device": "/dev/sdz"
            }
        ],
        "Tags": [
            {
                "Value": "volume3",
                "Key": "Name"
            },
            {
                "Value": "00:00",
                "Key": "Start"
            },
            {
                "Value": "00:20",
                "Key": "Finish"
            },
            {
                "Value": "2",
                "Key": "Period"
            }
        ],
        "VolumeId": "vol-33333333"
    }
]
}

Using jq, I am able to extract the following information:

VolumeId,Finish,Start,Period

using the jq command

cat json | jq -r '[.Volumes[]|({VolumeId}+(.Tags|from_entries))|{VolumeId,Finish,Start,Period}]'

[
  {
    "VolumeId": "vol-11111111",
    "Finish": "00:20",
    "Start": "00:00",
    "Period": "2"
  },
  {
    "VolumeId": "vol-22222222",
    "Finish": "00:20",
    "Start": "00:00",
    "Period": "2"
  },
  {
    "VolumeId": "vol-33333333",
    "Finish": "00:20",
    "Start": "00:00",
    "Period": "2"
  }
]

All this works fine. However I have the need to additional extract .Attachments.Device. I am looking for output for each array similar to:

 [
  {
    "VolumeId": "vol-11111111",
    "Finish": "00:20",
    "Start": "00:00",
    "Period": "2",
    "DeviceId": "/dev/sdz"
  },
  {
    "VolumeId": "vol-22222222",
    "Finish": "00:20",
    "Start": "00:00",
    "Period": "2",
    "DeviceId": "/dev/sdz"
  },
  {
    "VolumeId": "vol-33333333",
    "Finish": "00:20",
    "Start": "00:00",
    "Period": "2",
    "DeviceId": "/dev/sdz"
  }
]

However I can't figure out how to do this without getting an error. The most logical approach for me would be to do something like:

cat json | jq -r '[.Volumes[]|({VolumeId}+(.Attachments|from_entries)+(.Tags|from_entries))|{VolumeId,Finish,Start,Period,DeviceId}]'

However I get the error:

jq: error (at <stdin>:91): Cannot use null (null) as object key

Any help figuring out what I am not doing correct and how to fix it would be greatly appreciated.

thanks

2
  • Please fix the JSON. "Attachments": "Attachments": is incorrect. Commented Apr 4, 2016 at 3:04
  • @peak: apologies; fixed Commented Apr 4, 2016 at 4:10

1 Answer 1

2

Ultimately, the problem is that you're using from_entries on the Attachments array when it wouldn't work. from_entries takes an array of key/value pair objects to create an object with those values. However, you don't have key/value pairs, but objects. If you're just trying to combine them, you should use add.

Also, there is no property named DeviceId, it's Device. If you want to select the Device property and get it as DeviceId, you need to provide the correct name.

.Volumes | map(
    ({ VolumeId } + (.Attachments | add) + (.Tags | from_entries))
      | { VolumeId, Finish, Start, Period, DeviceId: .Device }
)
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your response. You are right; it's 'Device' and not 'DeviceId'. Unfortunately though this is not the root cause of the issue. It appears to be with +(.Attachments|from_entries) that causes the error, which is needed for me to pull .Attachments[]. +(.Tags|from_entries) works fine
Ah, right. Now it's clear what the problem is. I'll update.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.