Москва: проверенные б/у ноутбуки с гарантией и проверкой перед оплатой
+7 906 722-94-45

Главная → Статьи → Разбор больших логов: grep, jq и awk на ноутбуке

Анализ логов командной строкой: grep, jq и awk против файлов на гигабайты

Практические приёмы разбора логов: быстрые фильтры grep, агрегации awk, разбор JSON через jq, подсчёт топ-ошибок и работа с многогигабайтными файлами без специальных систем.

Прямой ответ

Прежде чем заводить ELK-стек для разового разбора, вспомните: связка grep | awk | jq разбирает гигабайтные логи за секунды прямо на ноутбуке. Базовый набор, закрывающий 90% вопросов «что происходило»: grep -c ERROR app.log (сколько), grep ERROR app.log | head (примеры), awk '{print $7}' access.log | sort | uniq -c | sort -rn | head (топ-URL), jq 'select(.level=="ERROR") | .message' app.log | sort | uniq -c (топ-ошибок в JSON-логах). Всё это работает на файле любого размера, потому что утилиты потоковые: память не расходуется, скорость упирается в диск.

Grep: первый проход по файлу

Флаги, которые превращают grep в инструмент анализа: -c (подсчёт), -i (регистр), -E (расширенные регулярки), -A/-B/-C n (n строк контекста после/до/вокруг — бесценно для стектрейсов), -o (только совпавшая часть — для извлечения полей), -v (инверсия), --color=always в связке с less. Типовые проходы: «найти все уникальные ошибки» — grep -oE 'ERROR [A-Za-z]+' app.log | sort -u; «что изменилось после деплоя» — grep '2026-10-20T1[45]:' app.log | grep -c ERROR в сравнении с прошлым часом; «найти запрос по id» — grep -C 5 'req-abc123'. Регулярные выражения в grep подчиняются тем же правилам производительности, что разобраны в статье про regex — на гигабайтных файлах неудачный паттерн виден сразу.

Awk: агрегации по колонкам

awk — это «микро-язык для табличных строк», и его конёк — подсчёты без программирования. Классика для access-логов:

# топ-10 IP по числу запросов
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head

# средний размер ответа и сумма по статусу
awk '$9==200 {s+=$10; n++} END {print "avg", s/n, "bytes over", n}' access.log

# распределение статусов
awk '{print $9}' access.log | sort | uniq -c

# запросы дольше секунды (время в поле 13, мс)
awk '$13 > 1000 {c++} END {print c " slow requests"}' access.log

Модель проста: каждая строка разбивается на поля $1..$NF, условие перед блоком фильтрует, END-блок подводит итог. Когда команда обрастает третьим условием — это сигнал, что пора перенести её в скрипт (принципы — в статье про автоматизацию).

Jq: разбор JSON-логов

Для структурированных логов (почему они лучше текстовых — в статье про структурированное логирование) jq незаменим:

jq -r 'select(.level=="ERROR") | [.timestamp, .message] | @tsv' app.log
jq -r 'select(.level=="ERROR") | .message' app.log | sort | uniq -c | sort -rn | head
jq -s 'map(select(.request_id=="req-42")) ' app.log     # -s: весь файл как массив
jq -r 'select(.duration_ms != null) | .duration_ms' app.log | sort -n | awk '{a[NR]=$1} END {print "p95:", a[int(NR*0.95)]}'

Последняя строка — 95-й перцентиль длительности одной командой. Полезные флаги: -r (сырые строки без кавычек), -c (компактный вывод для дальнейших фильтров), -e (код возврата по результату — для скриптов). На «нечистом» файле (часть строк не JSON) добавьте jq -R 'fromjson? // empty' — битые строки пропускаются молча.

Работа с гигантскими и живыми файлами

Файл на 10 ГБ не помещается в редактор, но потоковым утилитам всё равно — они читают последовательно. Приёмы: срез по времени через grep по префиксу таймстампа до тяжёлых фильтров (уменьшает объём в разы); zgrep для ротированных .gz; less +F для «живого хвоста» с поиском (или tail -f | grep --line-buffered в отдельной панели tmux — организация терминала в статье про tmux); параллельный grep по нескольким файлам — grep -r или xargs с -P. Если разбор становится регулярным — сохраните конвейер как цель make/just-файла: «разбор инцидента» из десяти команд не должен каждый раз собираться заново.

Когда CLI уже не хватает

Границы честные: интерактивная визуализация, корреляция логов нескольких сервисов по времени, полнотекстовый поиск по историческим данным — это зона лог-платформ (Loki/ELK). Признак, что вы уперлись: разбор одного инцидента требует десятка ручных конвейеров по нескольким машинам. До этого рубежа — а на локальном стеке он достигается нескоро — grep/jq/awk быстрее любой системы по времени «от вопроса к ответу».

Готовые рецепты: от инцидента к ответу за минуту

Набор конвейеров, которые покрывают типовые вопросы разбора. «Когда началось?» — частота ошибок по минутам: вырезать таймстампы ошибок, сгруппировать по минутам, найти первую аномальную. «Что именно сломалось?» — топ сообщений об ошибках через jq с сортировкой по количеству: обычно 80% инцидента — одна повторяющаяся причина. «Кого затронуло?» — уникальные идентификаторы пользователей/запросов в ошибках: одна строка с sort -u отвечает на вопрос масштаба. «Стало ли лучше после фикса?» — тот же подсчёт по минутам до и после деплоя, сравнение занимает секунды.

Эти четыре вопроса — скелет любого разбора, и каждый закрывается однострочником. Сохраняйте удачные конвейеры: в alias, в just-цели, в заметки — коллекция рецептов растёт и через год разбор типового инцидента занимает минуты. Отдельный навык — комбинация с less: открыть найденное в less, найти контекст (/паттерн), вернуться к фильтрации — цикл «сузить → изучить → сузить» быстрее, чем попытки угадать идеальный фильтр с первого раза.

FAQ

Чем sort | uniq -c лучше awk-подсчёта? Ничем — это идиома; awk может то же одним проходом ({c[$1]++} END {for (k in c) print c[k], k}), но конвейер sort|uniq читается всеми и на малых объёмах разницы нет.

Как искать по нескольким условиям? Цепочка grep'ов (grep A | grep B) читается проще составного регулярного выражения; на больших файлах один проход awk с двумя условиями быстрее двух grep — но измеряйте, а не верьте на слово.

Есть ли это в Windows? В WSL — полноценно; в PowerShell аналоги — Select-String, ConvertFrom-Json, Measure-Object. Для серьёзного разбора логов WSL-окружение удобнее.

Что быстрее: grep или специализированный ripgrep? ripgrep (rg) обычно быстрее на больших деревьях файлов (параллелизм, умные пропуски), синтаксис совместим по духу; в конвейерах заменяет grep почти без правок.

Чем помочь себе на неструктурированных логах? Приведите к табличному виду один раз: grep -oE с именованными частями или sed-подстановка превращают строку в разделённые поля — дальше работает awk. Разовое усилие окупается на всех последующих вопросах к этому файлу.

Как быстро посмотреть распределение по времени? Вырежьте час/минуту из таймстампа и прогоните через uniq -c: awk '{print substr($1,12,5)}' app.log | uniq -c даст построчную гистограмму активности без единого графического инструмента — всплеск виден глазами сразу.

Есть ли смысл учить sed вместе с awk? Для задач разбора логов sed нужен в одной роли — быстрые подстановки при подготовке строк к awk (нормализация разделителей, вырезание префиксов). Глубоко изучать его ради этого не требуется: три-четыре идиомы покрывают почти все практические случаи, а сложная логика всё равно уходит в awk или скрипт.

Источники: мануалы GNU grep/gawk, jq manual (ссылки в шапке).