2016-10-14 5 views
1

Здесь выводится все ec2-instance.json из EC2-описывающих-экземпляров:Многоуровневая массив JSON рендеринга с JQ

{ 
    "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. Теперь я мог использовать следующий синтаксис для получения значения экземпляра Tag, а также EBS volumeid:

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

, но если я хочу, чтобы получить другое значение из массива BlockDeviceMappings у меня будет неправильный результат, что означает, что я не могу правильно отобразить значение массива различных уровней, например Значение тега и VolumeId и DeviceName, я все равно получаю избыточность вывода. Я пробовал:

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

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

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

В 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 
+1

Было бы полезно, если ваш вопрос включен нужный выход из запроса вы собираетесь построить - это сделало бы легко определить, правилен ли данный ответ, и уменьшить неуместную ориентацию на конкретный механизм, который вы в настоящее время ожидаете использовать для построения этого запроса (что, в общем, указывает на проблему [XY] (http://xyproblem.info /)). –

ответ

2

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

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

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

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

cat all-ec2-instance.json \ 
| jq -r '.Reservations[].Instances[] | .Tags[].Value +" "+(.BlockDeviceMappings[] | .Ebs.VolumeId +" "+ .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" 

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

+0

Это работает! Но я не могу найти круглые скобки в руководстве jq, поэтому никогда не знаю, что мы можем использовать это для создания еще одного изолированного цикла массива. Где в руководстве jq я могу найти использование круглых скобок (и как создать цикл изоляции)? Я использую это руководство: https://stedolan.github.io/jq/manual/ – sylye

+1

это зависит от того, что вы хотите сделать, но так как вы хотели объединить строки, вам нужны скобки (как математический метод), вы можете проверить полное руководство, есть несколько примеров, которые используют скобки, но у них нет отдельной главы, посвященной их обычаям –

1

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

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

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

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

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

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

+0

Да, я это понял. но я хочу знать, как решить эту проблему в bash, так как в будущем мне понадобится другой json-файл. Однако ваш вклад также оценен! – sylye

+0

Язык запросов, который использует CLI, также имеет инструмент командной строки 'jp' –

+0

@JordonPhillips. Я думаю, что OP означал, что он захочет работать с файлом JSon, который может быть получен из результата AWS CLI или чего-то еще –

Смежные вопросы