Если вы часто работаете с текстами формата JSON из командной строки или в шелл-скриптах, вы можете задаться вопросом, есть ли какая-то консольная утилита, которая может распарсить JSON-строку. Консольный JSON-парсер может быть удобен, когда вы тестируете или отлаживаете сетевые JSON-сервисы. Вы можете скормить ответы формата JSON от веб-сервиса консольному JSON-парсеру, тем самым легко изучая трудночитаемые JSON-ответы или извлекая из них отдельные объекты.

В этом руководстве я покажу, как распарсить JSON-строку из командной строки.

В Linux есть консольный JSON-процессор jq, который делает то, что нам необходимо. Используя jq, вы можете парсить, фильтровать, мапить и преобразовывать JSON-структуру данных без особых усилий.

Установите jq из репозитория вашего дистрибутива Linux.

Для Debian и Ubuntu:

$ sudo apt-get install jq

Для Fedora:

$ sudo dnf install jq

Для openSUSE:

$ sudo zypper install jq

Также вы можете установить jq, просто скачав его бинарник (доступен отдельно для 32- и 64-битной систем), как показано далее.

$ wget http://stedolan.github.io/jq/download/linux32/jq # (32-битная система)
$ wget http://stedolan.github.io/jq/download/linux64/jq # (64-битная система)
$ chmod +x ./jq
$ sudo mv jq /usr/local/bin

Бинарник jq также доступен для Windows, OS X и Solaris платформ, а его полный исходный код выпущен под лицензией MIT.

Следующие примеры показывают, как парсить JSON-структуру данных с помощью jq.

Пример JSON-схемы:

$ cat json.txt

{
        "name": "Google",
        "location":
                {
                        "street": "1600 Amphitheatre Parkway",
                        "city": "Mountain View",
                        "state": "California",
                        "country": "US"
                },
        "employees":
                [
                        {
                                "name": "Michael",
                                "division": "Engineering"
                        },
                        {
                                "name": "Laura",
                                "division": "HR"
                        },
                        {
                                "name": "Elise",
                                "division": "Marketing"
                        }
                ]
}

Чтобы распарсить JSON-объект:

$ cat json.txt | jq '.name'

"Google"

Чтобы распарсить вложенный JSON-объект:

$ cat json.txt | jq '.location.city'

"Mountain View"

Чтобы распарсить JSON-массив:

$ cat json.txt | jq '.employees[0].name'

"Michael"

Чтобы извлечь конкретные поля из JSON-объекта:

$ cat json.txt | jq '.location | {street, city}'

{
  "city": "Mountain View",
  "street": "1600 Amphitheatre Parkway"
}
Поделиться с друзьями
-->

Комментарии (23)


  1. kvaps
    11.07.2016 01:26

    Прикольно, спасибо за тулзу, интересно: есть ли что то подобное для yaml?


    1. symbix
      11.07.2016 02:45
      +3

      ну… например
      alias yaml2json=«ruby -ryaml -rjson -e 'puts JSON.pretty_generate(YAML.load(ARGF))'»

      cat file.yaml | yaml2json | jq…


    1. eugen-du
      11.07.2016 15:31
      +1

      Я начал пользоваться «shyaml» отсюда: github.com/0k/shyaml.


  1. reji
    11.07.2016 01:51
    +3

    Использую для этого питон, который есть практически везде:

    python -m json.tool

    Примеры на других языках: http://stackoverflow.com/questions/352098/how-can-i-pretty-print-json

    upd: да, там нет ответа на запрос «показать конкретное значение», но это решает ещё парой слов


    1. novoxudonoser
      11.07.2016 17:11
      +1

      Зашёл чтобы написать — «А потом плюнуть и использовать python», но меня опередили.


  1. ciiccii
    11.07.2016 02:08
    -4

    Вот пример как достать значение из json на баше и авк:

    function jsonval {
        temp=`echo $json | sed 's/\\\\\//\//g' | sed 's/[{}]//g' | awk -v k="text" '{n=split($0,a,","); for (i=1; i<=n; i++) print a[i]}' | sed 's/\"\:\"/\|/g' | sed 's/[\,]/ /g' | sed 's/\"//g' | grep -w $prop`
        echo ${temp##*|}
    }
    
    json=$(curl -s $link)
    prop=$prop_name
    TMP=`jsonval`
    


    1. iqiaqqivik
      11.07.2016 10:54
      +3

      Во-первых, на sed’е и awk. Во-вторых, sed уже лет 20 принимает несколько параметров s//, не нужно гонять весь файл через несколько sed’ов.


    1. ultrinfaern
      11.07.2016 10:55
      +7

      Парсим контекстно-свободные грамматики регулярными выражениями? Ну, ну…


      1. ciiccii
        12.07.2016 13:55

        https://habrahabr.ru/post/171667/


  1. sleeply4cat
    11.07.2016 02:59
    +5

    > wget jq
    > chmod +x jq
    > mv jq /usr/local/bin

    господи D:

    Я понимаю, что это перевод, но почему такой способ установки преподносится как основной?..


    1. Indexator
      11.07.2016 03:56

      Это был единственный способ в оригинале) Поэтому от себя добавил установку через репозиторий как второй способ. Сейчас поменял их местами. :)


  1. nibogd
    11.07.2016 02:59
    +3

    Есть утилита, вдохновлённая этой, но для xml/html: github.com/EricChiang/pup


  1. shushu
    11.07.2016 06:57

    Ожидал увидеть решение на bash.


    1. iRandom
      11.07.2016 10:54

      echo json.txt | grep -Po '(?


    1. kalterfive
      11.07.2016 13:43
      +1

      Если не в шеллах, то где ещё использовать эту утилиту?


  1. E_STRICT
    11.07.2016 07:15
    +2

    Хорошо подходит для `docker inspect`.


    1. shushu
      11.07.2016 07:23
      +2

      У докер инспекта и так есть инструменты для этого. Например:

      docker inspect -f '{{ .NetworkSettings.IPAddress }}' <containerID>
      

      выведет IP адресс


  1. Odondon_Labama
    11.07.2016 10:54
    +3

    Есть ещё лайфхак для vi / vim. Уже открыв json файл его можно декодировать:
    :%!jq.
    И потом кодировать обратно:
    :%!jq -c.


  1. yarkov
    11.07.2016 10:55

    Спасибо большое за статью. Очень пригодилась.


  1. ilyasher
    11.07.2016 10:55
    +2

    Если JSON большой и структура его не ясна (пример: ответ AWS API) можно использовать github.com/ilyash/show-struct (моя разработка), который покажет структуру в виде возможных аргументов (paths) для JQ.

    Более радикальное решение для работы с структурированными данными в шелле:… Шелл который поддерживает структурированные данные и в котором не нужен JQ. Я работаю над этим: github.com/ilyash/ngs. Пример: instances = ``aws ec2 describe-instances $*filters``


  1. vsb
    11.07.2016 11:24

    Хороший инструмент. Использую иногда в скриптах. У него значительно больше возможностей, чем это описано в статье, по сути там свой маленький язык программирования для преобразования JSON.


  1. PastorGL
    11.07.2016 13:20
    +2

    Полезная утилита. Недавно здорово выручила для нужд CI — парсить/трансформить из шелла JSON ответ Stash со списком PR оказалось в разы проще и удобнее, чем настраивать хуки или писать расширения. Надо будет собраться и написать статейку.


  1. random1st
    11.07.2016 13:52

    python -c «import json; json.loads...»