AWS CLI / jq - преобразование JSON с помощью тегов и отображение информации даже для неопределенных тегов - PullRequest
0 голосов
/ 02 мая 2018

Я столкнулся с проблемой при попытке обработать вывод команды 'aws ec2 description-instances' с помощью 'jq', и мне действительно нужна помощь.

Я хочу преобразовать вывод JSON в файл CSV со списком всех экземпляров, с столбцы «Имя, InstanceId, Tag-Client, Tag-CostCenter».

Я использовал команду выбора jq с такой командой:

aws ec2 describe-instances |
  jq -r '.Reservations[].Instances[]
    | (.Tags[]|select(.Key=="Name")|.Value) + "," + .InstanceId + "," 
      + (.Tags[]|select(.Key=="Client")|.Value) + ","
      + (.Tags[]|select(.Key=="CostCenter")|.Value)'

Однако при использовании селекторов таким способом отображаются только те записи, которые содержат все теги, а не те, которые содержат только один из тегов.

Я понимаю поведение, которое похоже на grep, но я пытаюсь выяснить, возможно ли выполнить эту операцию с помощью jq, поэтому в случае, если один тег не определен, просто вернет строку "" и не удаляйте всю строку.

Я нашел ссылку на использование предложений «если» в jq ([https://ilya -sher.org / 2016/05/11 / most-jq-you-когда-либо-нужно-] /] , но кто-то интересуется, разрешил такой случай, не прибегая к этой логике и не разбивая команду на разные исполнения.

1 Ответ

0 голосов
/ 03 мая 2018

Всякий раз, когда вам дается массив пар ключ / значение (теги здесь), и вы хотите извлечь значения по их ключу, вам будет проще отобразить их в объект, чтобы вы могли обращаться к ним напрямую. Функции вроде from_entries будут хорошо работать с этим.

Однако, поскольку вы также пытаетесь получить значения, не входящие в этот массив тегов, вы можете подойти к нему немного по-другому, чтобы сохранить некоторые шаги. Используя reduce или foreach, вы можете пройти через каждый из тегов и добавить его к объекту, который содержит все интересующие вас значения. Затем вы можете отобразить нужные значения в массив, а затем преобразовать в CSV. строки.

Таким образом, если ваша цель - создать строки по Tags[Name], InstaceId, Tags[Client], Tags[CostCenter] для каждого экземпляра, вы можете сделать это:

# for each instance
.Reservations[].Instances[]
# map each instance to an object where we can easily extract the values
  | reduce .Tags[] as $t (
        { InstanceId }; # we want the InstanceId from the instance
        .[$t.Key] = $t.Value # add the values to the object
    )
# map the desired values to an array
  | [ .Name, .InstanceId, .Client, .CostCenter ]
# convert to csv
  | @csv

И хорошей новостью является то, что если Name, Client или CostCenter не существует в массиве тегов или даже InstanceId, то они просто будут null, которые становятся пустыми, когда преобразован в CSV.

...