JQ парсер JSON

Описание команд и синтаксиса парсера JSON

Памятка по jq (командный процессор для JSON)

jq — это мощный и гибкий инструмент командной строки для парсинга, фильтрации, преобразования и форматирования JSON-данных.


1. Базовый синтаксис вызова

# Чтение из файла
jq [опции] <фильтр> [файл.json]

# Чтение из stdin (стандартного ввода)
cat файл.json | jq [опции] <фильтр>

Основные опции:

  • -r (--raw-output): Выводит строки без кавычек (например, для plain-text).
  • -c (--compact-output): Выводит JSON в одну компактную строку, а не в красивом формате.
  • -s (--slurp): Обрабатывает весь входной поток как один большой массив JSON.
  • --arg var value: Позволяет передавать переменные в скрипт jq из командной строки.

2. Основные фильтры и операции

Команда/Фильтр Описание Пример (вход → выход)
. Просто выводит входные данные в отформатированном виде. jq '.' data.json
.key Обращение к полю объекта. {"name": "Alice"} → "Alice"
.[] Разворачивает массив в поток элементов или объект в поток значений. [1,2,3] → 1, 2, 3
.[index]
.[start:end]
Обращение к элементу массива по индексу или к срезу. `[10,20,30]
, Оператор запятой применяет несколько фильтров. jq '.name, .age'
| Пайп (конвейер) передает вывод одного фильтра на вход другого. jq '.[] | .name'
select(условие) Фильтрует элементы, удовлетворяющие условию. jq '.[] | select(.age > 30)'
map(фильтр) Применяет фильтр к каждому элементу массива. jq 'map(.age)'
length Возвращает длину массива или строки. jq '.names | length'
keys Возвращает ключи объекта в виде массива. jq '.user | keys'
has("key") Проверяет, существует ли ключ в объекте. jq 'map(has("email"))'
del(.path) Удаляет указанное поле. jq 'del(.user.password)'
// default Оператор по умолчанию. jq '.email // "no email"'

3. Создание новых объектов и массивов

Команда Описание Пример
{} Создание нового объекта. jq '{имя: .user, лет: .age}'
[] Создание нового массива. jq '[.user, .age]'
+, -, *, /, % Математические операции. jq '.items | length + 1'
= / |= Присваивание (обычно внутри {}). jq '.new_field = "value"'
jq '.age |= .+1'

4. Условные конструкции и функции

# Условие if-then-else-end
if .age >= 18 then "adult" else "child" end

# Определение функции (синтаксис похож на JavaScript)
def increment: . + 1;
.[] | increment

# Работа со строками
jq '.[] | "Name: \(.name), Age: \(.age)"'  # - Интерполяция строк
jq '.[] | .name | test("[Aa]lice")'        # - Регулярные выражения (test, match)

5. Работа с вложенными структурами (рекурсивный спуск)

Команда Описание
.. Рекурсивный спуск. Находит все значения по пути, независимо от глубины вложенности. Очень мощный инструмент.

Пример: Дан JSON:

{
  "company": {
    "name": "Tech Corp",
    "employees": [
      {"name": "Alice", "email": "alice@example.com"},
      {"name": "Bob", "email": "bob@example.com"}
    ]
  }
}

Команда:

jq '.. | .email? // empty' data.json

Результат:

"alice@example.com"
"bob@example.com"
  • .. проходит через каждый элемент в JSON.
  • .email? пытается получить поле email для каждого элемента. Вопросительный знак ? подавляет ошибки, если поля нет.
  • // empty отбрасывает все null или ложные результаты, оставляя только найденные email-адреса.

6. Практические примеры

Данные для примеров (data.json):

{
  "users": [
    {"id": 1, "name": "Alice", "age": 25, "active": true},
    {"id": 2, "name": "Bob", "age": 35, "active": false},
    {"id": 3, "name": "Charlie", "age": 28, "active": true}
  ]
}
  1. Получить все имена:

    jq '.users[].name' data.json
    # или
    jq '.users | map(.name)' data.json
    
  2. Получить имена только активных пользователей:

    jq '.users[] | select(.active == true) | .name' data.json
    
  3. Создать новый JSON с полным именем и флагом “is_adult”:

    jq '.users[] | {userName: .name, isAdult: (.age >= 18)}' data.json
    
  4. Использование внешней переменной (–arg):

    jq --arg user_id 2 '.users[] | select(.id == ($user_id | tonumber))' data.json
    
  5. Подсчитать количество пользователей:

    jq '.users | length' data.json