Зачем jq
HTTP API всё больше отдают JSON, ядро kubectl/docker/gh/aws
тоже умеет в JSON. Парсить регулярками - больно и хрупко. jq -
фактический стандарт для CLI-обработки JSON: один бинарник без
зависимостей, фильтр-язык похож на XPath/jsonpath, но мощнее.
Альтернатива - Python python -c 'import json,sys;...' - читается
тяжелее в pipe.
Базовый синтаксис
jq [OPTIONS] FILTER [FILE...]
Без файла читает stdin. Самый простой filter - . (identity):
curl -s api.example.com/users | jq .
Это уже даёт цветной pretty-print - часто этого достаточно.
Селекторы
jq '.name' # поле name
jq '.users[0]' # первый элемент массива
jq '.users[]' # ВСЕ элементы как поток (не массив)
jq '.users[].email' # поле email каждого
jq '.users | length' # длина массива
jq '.users | keys' # ключи объекта (или индексы массива)
jq '.["weird-key"]' # ключи с дефисами/пробелами через []
jq '..|.email? // empty' # рекурсивный поиск email где угодно
select() - фильтрация
# Активные пользователи
jq '.users[] | select(.active == true)'
# ID юзеров с >100 коммитов
jq '.users[] | select(.commits > 100) | .id'
# Pod'ы в статусе CrashLoopBackOff
kubectl get pods -o json | jq '
.items[]
| select(.status.containerStatuses[]?.state.waiting.reason == "CrashLoopBackOff")
| .metadata.name'
? после поля = "если нет ключа, не падай, просто пропусти".
Трансформация
# Только имя и email каждого юзера, как массив объектов
jq '.users | map({name, email})'# Из массива объектов в плоский TSV
jq -r '.users[] | [.id, .name, .email] | @tsv'
# Из массива в CSV с заголовком
jq -r '(.users[0] | keys_unsorted), (.users[] | [.[]]) | @csv'
# Группировка
jq 'group_by(.team) | map({team: .[0].team, count: length})'Форматтеры на конце: @tsv, @csv, @sh (escape для bash),
@json, @uri, @base64, @base64d.
-r и -c
-r(raw output) - снимает JSON-кавычки со строк. Без-r:"foo", с-r:foo. Нужен когда передаёшь дальше в shell.-c(compact) - один объект на строку без переносов. Удобно для NDJSON-логов иxargs.-s(slurp) - прочитать весь stdin как один массив. По дефолту jq читает поток JSON-документов.
# NDJSON: один объект на строку
cat events.jsonl | jq -c 'select(.severity=="ERROR")'
# Извлечь IP'ы для xargs
jq -r '.hits[].ip' alerts.json | sort -u | xargs -I{} whois {}Переменные и параметры
# Передать значение из shell
jq --arg user "$USER" '.users[] | select(.login == $user)' data.json
# Числовое (не строкой)
jq --argjson min 100 '.events[] | select(.duration_ms > $min)' data.json
Без --arg shell-подстановки в фильтре - частый источник
injection-багов. Не делай jq ".x == \"$VAR\"", делай
jq --arg v "$VAR" '.x == $v'.
Reduce, foreach, paths
Для агрегации:
# Сумма поля size
jq '[.files[].size] | add'
jq '.files | reduce .[] as $f (0; . + $f.size)'
# Все пути до листьев (для отладки структуры)
jq '[paths(scalars)]'
jq и kubectl/docker/aws
Все три CLI отдают -o json или --format=json:
# Ноды и их kubelet-версия
kubectl get nodes -o json | jq -r '.items[] | [.metadata.name, .status.nodeInfo.kubeletVersion] | @tsv'
# Контейнеры по образу
docker ps --format='{{json .}}' | jq -r 'select(.Image | contains("nginx")) | .Names'# Все S3-бакеты с тегом owner=team-x
aws s3api list-buckets | jq -r '.Buckets[].Name' \
| xargs -I{} sh -c 'aws s3api get-bucket-tagging --bucket {} 2>/dev/null \ | jq -r --arg b {} ".TagSet[] | select(.Key==\"owner\" and .Value==\"team-x\") | \"\($b)\""'Когда что-то пошло не так
jq: error: Cannot index ... with ...- применил.fieldк не-объекту (массиву, null, числу). Используй?илиselect(type=="object").nullв выводе вместо ошибки -?глотает ошибки. Сними?, чтобы увидеть где сломалось.- Кавычки в выводе мешают - забыл
-r. - Переносы строк в значениях -
-rотдаст с физическими\n, может ломать pipe вawk. Решение:@csv/@tsvили-c+ парсер. - Большой файл лагает - jq читает весь stream в память при
-s. Без-sон стримит. Для гигабайтных файлов смотри gojq или jaq. - JSON5/JSONC (с комментариями) - jq не парсит. Сначала прогони
через
yq -p jsonилиjqпосле удаления комментариев.
Альтернативы
yq(Mike Farah) - jq-совместимый синтаксис для YAML/TOML/XMLgojq- Go-реализация, чуть быстрее на больших файлахjaq- Rust, ещё быстрее, не 100% совместим с фичамиfx- интерактивный JSON-explorer (TUI)jless- jq + less = листать большой JSON