Раздел 13 · Tools

Инструменты исследования: jq, ripgrep, awk и друзья

middle-senior~20 мин

без входаВойди, чтобы отмечать прогресс, вести заметки и решать задачи в редакторе. войти

Инструменты исследования: jq, ripgrep, awk и друзья

Третий урок раздела. Когда нужно быстро ответить на вопрос “что происходит в этих данных”, тяжёлый скрипт обычно избыточен. Набор острых CLI-инструментов отвечает за секунды и помещается в одну строку. Разница между разработчиком, который пишет на каждый вопрос скрипт на тридцать строк, и тем, кто собирает ответ конвейером из трёх утилит, это разница в темпе работы на порядок. Этот урок про то, как думать конвейером.

Идея: каждый инструмент это маленький язык под свой тип данных

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

  • Текст и код: ripgrep (rg), поиск по содержимому.
  • Файлы по имени: fd, поиск по дереву.
  • JSON: jq, срезы и трансформации.
  • YAML: yq, тот же jq для YAML.
  • Таблицы и поля: awk, построчная обработка по колонкам.
  • Замены в потоке: sed, потоковый редактор.

Думать надо так: на входе у меня данные такого-то типа, я хочу из них такой-то ответ, какая цепочка маленьких языков ведёт от одного к другому.

ripgrep: поиск, который уважает проект

rg это grep, выросший для работы с кодовой базой. По умолчанию он рекурсивен, уважает .gitignore (не лезет в node_modules и dist), пропускает бинарники и работает заметно быстрее за счёт параллелизма.

rg "TODO" -t ts            # только в TypeScript-файлах
rg "createUser" -A 3 -B 1  # 3 строки после и 1 до совпадения
rg -l "useEffect"          # только имена файлов со совпадением
rg "v(\d+)\.(\d+)" -o      # вывести только сами совпадения по regex

Флаг -t фильтрует по типу файла, -A / -B дают контекст вокруг совпадения, -l отдаёт список файлов (удобно скормить дальше в xargs), -o печатает только совпавшую часть. Для поиска “где вообще используется эта функция” это первый инструмент, ещё до того, как лезть в редактор.

Файлы по имени ищет напарник fd: fd config найдёт все пути с config в имени, без громоздкого find . -name '*config*'.

jq: запросы к JSON

API, логи, конфиги, всё это JSON, и jq это маленький язык запросов к нему. Фильтр на входе получает JSON, на выходе отдаёт JSON, а | внутри jq соединяет фильтры так же, как | в shell соединяет команды.

# достать поле из каждого элемента массива
curl -s api/users | jq '.[].email'

# выбрать по условию и собрать проекцию
jq '.items[] | select(.price > 100) | {name, price}' data.json

# агрегат: средняя цена
jq '[.items[].price] | add / length' data.json

# разобрать массив JSON-строк (по одному объекту на строку)
jq -s 'sort_by(.latency) | reverse | .[0:10]' logs.json

Ключевые кирпичики: .field достаёт поле, .[] разворачивает массив в поток элементов, select(...) фильтрует, {a, b} собирает новый объект, sort_by / group_by / add агрегируют. jq -s (slurp) собирает поток JSON-объектов в один массив, это режим для построчных логов.

YAML обрабатывает yq с тем же синтаксисом, что незаменимо для Helm-values и compose-файлов.

дальше после входа

Урок целиком открыт всем, кто вошёл. Войди по своему email, чтобы читать дальше.

Вход пока по приглашению. Если хочешь учиться, напиши Vassiliy.