jq. | Кодементор

Что отличает хорошего разработчика от отличного разработчика?

В то время как хороший разработчик решает конкретную задачу (например, создает новый компонент React, редактирует конечную точку REST и т. д.), у отличного разработчика есть широкое понимание и набор инструментов которые могут помочь ему в различных ситуациях. (мой2с)

Одним из таких инструментов является jq — невероятный CLI инструмент с 13к+ звезд на Github. Вы можете видеть это как Швейцарский армейский нож для работы с JSON. Это очень полезно, когда вы хотите быстро понять данные в JSON; это сэкономило мне много времени за последние годы. Мне нравится использовать его, потому что это инструмент командной строки, и я люблю делать как можно больше работы в CLI. Это мой личный выбор — и другая тема.

посмотрим как jq могу помочь тебе!

Настраивать

Вы найдете все необходимые инструкции здесь. Все, что вам нужно сделать, это загрузить двоичный файл для используемой вами ОС и переместить его в место, где ОС ищет двоичные файлы, например /usr/local/bin — для линукс/макОС.

Кроме того, вы можете установить его с помощью менеджера пакетов (подходящего для вашей ОС). В macOS вы можете использовать заваривать

$ brew install jq

и в Ubuntu вы можете использовать

$ sudo apt-get install jq

Спасибо, Тео, за указание на это в разделе комментариев.

Полезные ресурсы: руководство, руководство а также детская площадка. Я настоятельно рекомендую вам посмотреть в руководстве все фильтры jq, используемые в этом посте.

Базовая информация

Как указано в руководство, каждая программа jq является фильтром. Он принимает входные данные (данные JSON) и производит выходные данные. Существует множество встроенных фильтров для извлечения того или иного поля объекта, или преобразования числа в строку, или различных других стандартных задач.

Сегодня мы собираемся изучить некоторые из этих фильтров.

Хватит болтать, давайте посмотрим на примеры

Вы уже видели один, который очень удобен: jq . краткая форма jq '.'. Эта команда напечатает весь JSON и украсит его, если он минимизирован.

я использую пародия для создания некоторых фиктивных данных. Здесь вы можете найти JSON, который я использую для тестов.

Давай попробуем jq .

Сначала давайте загрузим файл JSON

$ cd ~
$ curl -s  > mock.json

Теперь проверьте вывод этих команд:

$ cat mock.json

$ cat mock.json | jq .

Как было сказано ранее, jq . напечатает весь JSON, но украсит. Довольно круто, да?

Основная фильтрация: .[].а

Что, если нам нужны только электронные письма этих пользователей? Это проще, чем вы думаете.
Если вы внимательно посмотрите на вывод предыдущей команды, вы заметите, что корень JSON — это массив.

Чтобы получить все элементы этого массива, нет сам массив, вы можете использовать []. Вы можете думать об этом как разлагающийся массив.

$ cat mock.json | jq .[]

Чтобы получить только электронные письма, просто добавьте .emailпоэтому фильтр становится:

$ cat mock.json | jq .[].email

Массивы: индекс, вложенные фильтры

Чтобы получить первый элемент массива, все, что вам нужно сделать, это:

$ cat mock.json | jq .[0]

Конечно, вы можете добавить дополнительные фильтры для получения электронной почты из первого элемента или для получения онлайн-статуса первого устройства, используемого первым человеком:

$ cat mock.json | jq .[0].email
$ cat mock.json | jq .[0].devices[0].online

Примечание: jq .a.b.c а также jq '.a | .b | .c' дают тот же результат. Таким образом, мы достигли бы того же результата, если бы использовали:

$ cat mock.json | jq '.[0] | .email'
$ cat mock.json | jq '.[0] | .devices[0] | .online'

Длина: построение массива, длина, труба

Что делать, если вы хотите получить общее количество писем? Вы можете использовать wc -lконечно.

$ cat mock.json | jq .[].email | wc -l

Но вы также можете использовать length функция в jq. Давайте посмотрим на это в действии!

$ cat mock.json | jq '.[].email | length'

Не то, что вы ожидали, верно? На самом деле это длина строк, потому что length применяется ко всем значениям электронной почты (разложенный массив); length работает с массивами, строками и объектами. Так, например, делая jq '.[] | length' даст количество полей в каждом объекте.

Чтобы получить количество писем, все, что нам нужно сделать, это создать массив, что интуитивно понятно.

$ cat mock.json | jq '[.[].email] | length'

Вы можете спросить себя, что произойдет, если вы позвоните jq '. | length'. Это даст вам общее количество элементов в массиве, потому что он не был разрушен/разложен.

Фильтр: выбрать и, содержит, ==

Что, если вы хотите отфильтровать эти электронные письма? Вы можете использовать grepконечно.

$ cat mock.json | jq .[].email | grep @google

Но вы также можете использовать select.

$ cat mock.json | jq '.[].email | select(. | contains("@google"))'

Давайте добавим еще одно условие в наш фильтр, чтобы получить всех женщин с электронной почтой Google.

$ cat mock.json | jq '.[] | select((.email | contains("@google")) and .gender == "Female")'

Этот фильтр вернет 2 объекта (не электронные письма), потому что первый фильтр .[] возвращает объекты, которые мы фильтруем с помощью select((.email | contains("@google")) and .gender == "Female"). Если мы внимательно посмотрим на этот бит, мы увидим 2 условия .gender == "Female" а также (.email | contains("@google"). Трубка | используется для применения обоих select а также contains функции.

Примечание: Мы использовали конвейеры внутри команды jq для объединения фильтров и вызова length а также select. Помните об одинарных кавычках, используемых для инкапсуляции всех фильтров.

Если мы хотим получить только электронную почту, все, что нам нужно сделать, это подключить еще один фильтр.

$ cat mock.json | jq '.[] | select((.email | contains("@google")) and .gender == "Female") | .email'

Длина + Фильтр

Давайте узнаем, сколько женщин используют электронную почту Google. Нам нужно только построить массив и вызвать length.

$ cat mock.json | jq '[.[] | select((.email | contains("@google")) and .gender == "Female")] | length'

Нравится пока?

Построение объекта и интерполяция строк: {}, (.a)

Допустим, мы хотим иметь массив объектов, содержащий только 3 поля: first_name, last_name а также email. Нам нужно создать несколько новых объектов, и, опять же, синтаксис интуитивно понятен.

$ cat mock.json | jq '.[] | {first_name: .first_name, last_name: .last_name, email: .email}'

Как насчет конкатенации first_name а также last_name? Решением является интерполяция строк, аналогичная синтаксису JS.

$ cat mock.json | jq '.[] | {name: "\(.first_name) \(.last_name)", email: .email}'

Группировка: group_by

Еще одна крутая вещь, которую может сделать jq, — это группировка. Мы можем продемонстрировать это, сгруппировав по полу.

$ cat mock.json | jq group_by(.gender)

Это сработало, но результат не очень читабелен — это массив, который содержит 2 других массива, содержащих сгруппированные объекты. Давайте немного подкорректируем. Мы разложим 2 раза (так как у нас есть массив в массиве).

$ cat mock.json | jq 'group_by(.gender) | .[] | .[]'

И мы сформируем несколько новых объектов, используя технику, представленную выше.

$ cat mock.json | jq 'group_by(.gender) | .[] | .[] | {name: "\(.first_name) \(.last_name)", gender: .gender}'

Выглядит хорошо, но вещи все вместе. Мы хотим сохранить 2 разных массива с. Метод построения массива — наше решение.

$ cat mock.json | jq 'group_by(.gender) | .[] | [.[] | {name: "\(.first_name) \(.last_name)", gender: .gender}]'

Последняя вещь. Давайте посмотрим, сколько мужчин и сколько женщин в нашем наборе данных.

$ cat mock.json | jq 'group_by(.gender) | .[] | [.[] | {name: "\(.first_name) \(.last_name)", gender: .gender}] | length'

Выводы

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

Спасибо

Спасибо за чтение! Я надеюсь, это поможет.

Код включен!

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *