Множественный уровень json-рендеринга с jq

Вот все-ec2-instance.json вывод из ec2-describe-экземпляров:

{
    "Reservations": [
        {
            "OwnerId": "",
            "ReservationId": "",
            "Groups": [],
            "Instances": [
                {

                    "InstanceId": "i-11111111",
                    "Hypervisor": "xen",
                    "BlockDeviceMappings": [
                        {
                            "DeviceName": "/dev/sda1",
                            "Ebs": {
                                "Status": "attached",
                                "DeleteOnTermination": false,
                                "VolumeId": "vol-11111111",
                                "AttachTime": "2016-04-19T15:53:53.000Z"
                            }
                        },
                        {
                            "DeviceName": "/dev/sdf",
                            "Ebs": {
                                "Status": "attached",
                                "DeleteOnTermination": false,
                                "VolumeId": "vol-22222222",
                                "AttachTime": "2016-05-25T08:22:33.000Z"
                            }
                        },
                        {
                            "DeviceName": "/dev/sdg",
                            "Ebs": {
                                "Status": "attached",
                                "DeleteOnTermination": false,
                                "VolumeId": "vol-33333333",
                                "AttachTime": "2016-02-28T04:22:07.000Z"
                            }
                        }
                    ],
                     "Tags": [
                        {
                            "Value": "ec2-test1",
                            "Key": "Name"
                        }
                    ]
                }
            ]
        },
        {
            "OwnerId": "",
            "ReservationId": "",
            "Groups": [],
            "Instances": [
                {

                    "InstanceId": "i-22222222",
                    "Hypervisor": "xen",
                    "BlockDeviceMappings": [
                        {
                            "DeviceName": "/dev/sda1",
                            "Ebs": {
                                "Status": "attached",
                                "DeleteOnTermination": false,
                                "VolumeId": "vol-44444444",
                                "AttachTime": "2016-05-19T15:53:53.000Z"
                            }
                        },
                        {
                            "DeviceName": "/dev/sdf",
                            "Ebs": {
                                "Status": "attached",
                                "DeleteOnTermination": false,
                                "VolumeId": "vol-55555555",
                                "AttachTime": "2015-08-25T08:22:33.000Z"
                            }
                        },
                        {
                            "DeviceName": "/dev/sdg",
                            "Ebs": {
                                "Status": "attached",
                                "DeleteOnTermination": false,
                                "VolumeId": "vol-66666666",
                                "AttachTime": "2016-07-28T04:22:07.000Z"
                            }
                        }
                    ],
                     "Tags": [
                        {
                            "Value": "ec2-test2",
                            "Key": "Name"
                        }
                    ]
                }
            ]
        }
    ]
}

Это еще один вопрос из предыдущего ответа https://stackoverflow.com/a/39204803/567761 . Теперь я могу использовать следующий синтаксис для получения значения тега экземпляра, а также тома EBS :

cat all-ec2-instance.json |jq -r '.Reservations[] | .Instances[] |  .Tags[].Value  +" "+ .BlockDeviceMappings[].Ebs.VolumeId '

но если я хочу получить другое значение из массива BlockDeviceMappings, у меня будет неправильный результат, а это значит, что я не могу правильно отобразить значение массива разных уровней, например, значение тега и VolumeId и cat all - ec2 - instance . json | jq - c - r '.Reservations [] | .Instances [] | .Tags []. Value + "" + .BlockDeviceMappings []. Ebs.VolumeId + "" + .BlockDeviceMappings []. DeviceName ' , я все равно получаю избыточность вывода. Я пытался:

cat all-ec2-instance.json |jq -c -r '.Reservations[] | .Instances[] |  .BlockDeviceMappings[] |.Ebs.VolumeId +" "+ .DeviceName '

Я получу 16 результат, который ошибочен, предположим, что он всего 6. Если только с помощью VolumeId и DeviceName, которые находятся в одном уровне с массивом BlockDeviceMappings, мы можем сделать это:

jq

В , как мы сохраняем значение предыдущего уровня массива и назначаем его более позднему циклу массива? Я пробовал использовать переменные и другую функцию jq, но не успел :(ec2-test1,vol-11111111,/dev/sda1 ec2-test1,vol-22222222,/dev/sdf ec2-test1,vol-33333333,/dev/sdg ec2-test2,vol-44444444,/dev/sda1 ec2-test2,vol-55555555,/dev/sdf ec2-test2,vol-66666666,/dev/sdg

Вот нужный результат (запятая или любой другой разделитель в порядке):

cat all-ec2-instance.json 
| jq -r '.Reservations[].Instances[] | .Tags[].Value +" "+ .BlockDeviceMappings[].Ebs.VolumeId'

json,bash,amazon-ec2,jq,

1

Ответов: 2


2 принят

Я сделаю еще один ответ на работу с jq

Сначала вы можете переписать первый запрос

cat all-ec2-instance.json 
| jq -r '.Reservations[].Instances[] | .Tags[].Value +" "+(.BlockDeviceMappings[] | .Ebs.VolumeId +" "+ .DeviceName)'

Затем, если вы хотите добавить дополнительное значение из Json, например `DeviceName``

"ec2-test1 vol-11111111 /dev/sda1"
"ec2-test1 vol-22222222 /dev/sdf"
"ec2-test1 vol-33333333 /dev/sdg"
"ec2-test2 vol-44444444 /dev/sda1"
"ec2-test2 vol-55555555 /dev/sdf"
"ec2-test2 vol-66666666 /dev/sdg"

вы получаете следующее

aws ec2 describe-instances --query "Reservations[].Instances[].[BlockDeviceMappings[].Ebs.VolumeId, Tags[].Value]"

которые являются 6 линиями, которые вы ожидаете


1

Как я уже упоминал в своем ответе на ваш оригинальный пост, вы можете сделать большую часть его непосредственно из CLI AWS

получить значение тега экземпляра, а также тома EBS:

DeviceName

Если вы хотите расширить, чтобы получить DeviceNameполе

aws ec2 describe-instances --query "Reservations[].Instances[].[BlockDeviceMappings[].[DeviceName, Ebs.VolumeId], Tags[].Value]"

и если вы хотите сохранить текст (при запуске необработанных данных из jq) вы можете добавить --output textфлаг в команду CLI

JSON, баш, амазонка-ec2, JQ,
Похожие вопросы