Парсинг JSON на оболочке

Парсинг JSON на оболочке

Как можно проанализировать вывод JSON в оболочке?

Например, Amazon Web Services предоставляет CLI для получения статуса ваших экземпляров:

$ aws ec2 describe-instances <my_instance_id>

Но команда возвращает строку JSON. Вывод этой команды выглядит так:

$ aws ec2 describe-instances x12345
{
    "Reservations" :
     {  
            "OwnerId": "1345345"
            "Groups": [], 
            "SecurityGroups": [
               {
                  "Foo" : "yes"
                  "Bar" : "no
               }
             ]
     }
}

Существуют ли встроенные оболочки, которые можно использовать для анализа выходных данных JSON?

Например, я хотел бы сохранить в переменной оболочки FOOследующее output["Reservations"]["SecurityGroups"][0]{"Foo"}.

Если это поможет, меня особенно интересуют решения, которые могли бы работать из Zsh.

решение1

Насколько я понимаю, вы ищете значение "Foo". ЭтоДействительнолегко сделать с помощью инструмента командной строки оболочки jq. Это что-то вроде sedтого, что он реализует свой собственный вид языка парсера. Учитывая ваш пример:

json='
{
    "Reservations" :
     {  
            "OwnerId" : "1345345",
            "Groups" :  [],
            "SecurityGroups" : [
               {
                  "Foo" : "yes",
                  "Bar" : "no"
               }
             ]
     }
}'

jqможно получить yesтак же просто как:

printf %s "$json" |
jq '.[].SecurityGroups[0].Foo?'                                                

ВЫХОД

"yes"

Вы можете пройти по хэшу объекта или списку словаря, используя нотацию .dot, а индексированные массивы можно индексировать проще, с помощью, как вы, вероятно, догадались, числовых индексов в квадратных скобках. В команде выше я использую пустую форму индекса, чтобы указать, что я хочу, чтобы все итерируемые элементы этого уровня были расширены. Это может быть проще понять таким образом:

printf %s "$json" | jq '.[][]'

... который выводит все значения для элементов второго уровня в хэше и возвращает мне...

"1345345"
[]
[
  {
    "Foo": "yes",
    "Bar": "no"
  }
]

Это лишь поверхностный взгляд на jqвозможности . Это чрезвычайно мощный инструмент для сериализации данных в оболочке, он компилируется в один исполняемый двоичный файл в классическом стиле Unix, он, скорее всего, доступен через менеджер пакетов для вашего дистрибутива, и он очень хорошо документирован. Пожалуйста, посетите егоgit-страницаи убедитесь сами.

Кстати, еще один способ работы со слоистыми данными json— по крайней мере, чтобы получить представление о том, с чем вы работаете — может заключаться в том, чтобы пойти другим путем и использовать нотацию .dotдля разбиениявсезначения ввсетакие уровни как:

printf %s "$json" | jq '..'

{
  "Reservations": {
    "OwnerId": "1345345",
    "Groups": [],
    "SecurityGroups": [
      {
        "Foo": "yes",
        "Bar": "no"
      }
    ]
  }
}
{
  "OwnerId": "1345345",
  "Groups": [],
  "SecurityGroups": [
    {
      "Foo": "yes",
      "Bar": "no"
    }
  ]
}
"1345345"
[]
[
  {
    "Foo": "yes",
    "Bar": "no"
  }
]
{
  "Foo": "yes",
  "Bar": "no"
}
"yes"
"no"

Но, вероятно, гораздо лучше было бы просто использовать один из многочисленных методов обнаружения или поиска, которые jqпредлагаются для различных типов узлов.

решение2

Это ответ на вашу цель, но не на ваш вопрос. То есть вы можете достичь своей цели без использования парсера JSON.

Утилита AWS cli имеет возможность выводить только выбранные поля с использованием --queryаргумента. Это задокументированоздесь.

Например:

$ aws ec2 describe-instances \
  --query 'Reservations[0].Instances[0].SecurityGroups[0].GroupName' \
  --instance-id i-6b272337 \
  --output text
mongodb

При желании вы можете выбрать даже несколько полей:

$ aws ec2 describe-instances \
  --query 'Reservations[0].Instances[0].SecurityGroups[0].[GroupName,GroupId]' \
  --instance-id i-6b272337 \
  --output text
mongodb sg-710ffa14

И вы также можете показать несколько соответствующих структур:

$ aws ec2 describe-instances \
  --query 'Reservations[0].Instances[0].SecurityGroups[*].[GroupName,GroupId]' \
  --instance-id i-6b272337 \
  --output text
mongodb sg-710ffa14
default sg-a0243bcc

Связанный контент