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