Помню тот день, когда мне прислали архив с логами веб-сервера на 15 гигабайт. Открыть в редакторе? Компьютер завис на пятой минуте. Написать скрипт на Python? Времени не было, а результат нужен был вчера. Тогда я впервые по-настоящему понял, почему опытные администраторы так любят три команды: grep, sed и awk.
С тех пор прошло несколько лет, и теперь я разбираю логи быстрее, чем кто-то успевает запустить Excel. Хочу поделиться этим навыком, который превращает часы мучений в несколько строк в терминале.
Почему три утилиты лучше одной программы
В Linux есть философия, которая кажется странной новичкам: вместо одного мощного инструмента используй десяток мелких, но идеально заточенных под свою задачу. Grep ищет, sed правит, awk считает. Соединяешь их через вертикальную черту, и получается конвейер обработки данных, который справляется с терабайтами информации.
Эта концепция родилась не случайно. Когда каждая утилита делает одно дело, но делает его превосходно, ты можешь собирать решения как конструктор. Сегодня ищешь ошибки 404, завтра анализируешь попытки взлома SSH, послезавтра вытаскиваешь медленные SQL-запросы. Инструменты те же, меняется только порядок их соединения.
Grep: фильтр для текстового потока
Начнём с grep. Название расшифровывается как Global Regular Expression Print, но суть проще: покажи мне все строки, где встречается нужный шаблон. В огромном файле логов это первый рубеж обороны против информационного шума.
Базовый пример выглядит так:
grep "404" access.log
Команда пробежится по файлу и выведет только те строки, где упоминается 404. Но grep умеет больше. Добавишь флаг -i
, и поиск станет нечувствительным к регистру. Укажешь -c
, получишь просто число совпадений без самих строк. А -v
вообще инвертирует логику: показывает всё, кроме указанного шаблона.
Когда работаешь с логами, часто нужен контекст. Нашёл ошибку, но хочешь видеть, что было до и после неё? Тут помогают -A
и -B
:
grep -A 3 -B 2 "ERROR" application.log
Эта команда покажет каждую строку с ERROR плюс три строки после и две до. Иногда именно в окружении скрывается причина проблемы.
Sed: хирург текстовых потоков
Если grep - это фильтр, то sed - это редактор на лету. Stream Editor обрабатывает текст построчно, применяя заданные команды. Чаще всего его используют для замены одного текста на другой:
sed 's/ERROR/ALERT/g' log.txt
Конструкция s/старое/новое/g
означает substitution - подстановку. Буква g
в конце говорит: делай это глобально, для всех вхождений в строке, а не только для первого.
Но sed может и удалять строки. Скажем, в логах много отладочной информации, которая только мешает анализу:
sed '/DEBUG/d' application.log
Команда /DEBUG/d
находит строки с DEBUG и удаляет их из вывода. Исходный файл при этом не меняется, если только не добавишь флаг -i
.
В реальной работе sed часто используют для нормализации данных. Представь: в логах IP-адреса записаны с разными масками, где-то есть лишние пробелы, где-то нет. Одна команда sed приводит всё к единому виду, после чего с данными гораздо проще работать.
Awk: программируемый анализатор
А вот awk - это уже почти полноценный язык программирования, заточенный под обработку структурированного текста. По умолчанию он разбивает каждую строку на поля по пробелам и даёт к ним доступ через переменные $1, $2 и так далее.
Типичная строка в логе веб-сервера выглядит примерно так:
192.168.1.100 - - [18/Oct/2025:14:23:45 +0000] "GET /api/users HTTP/1.1" 200 1543
Здесь первое поле - IP-адрес, девятое - код ответа, десятое - размер ответа. Awk позволяет оперировать этими полями, будто работаешь с колонками таблицы:
awk '{print $1}' access.log
Команда выведет список всех IP-адресов из лога. Хочешь вывести только IP с кодом 404? Добавь условие:
awk '$9 == 404 {print $1}' access.log
Настоящая мощь awk проявляется, когда нужно агрегировать данные. Например, посчитать суммарный объём трафика по каждому IP:
awk '{traffic[$1] += $10} END {for (ip in traffic) print ip, traffic[ip]}' access.log
Тут создаётся ассоциативный массив, где ключ - IP-адрес, а значение - накопленная сумма байтов. Блок END выполняется после обработки всего файла и выводит итоговую статистику.
Решаем реальную задачу: ошибки 404 по IP
Теперь соберём всё вместе. Задача: найти в логах все ошибки 404, посчитать, сколько раз каждый IP получал такой ответ, и отсортировать результат по убыванию.
Начинаем с grep, чтобы отфильтровать нужные строки:
grep ' 404 ' access.log
Пробелы вокруг 404 важны: без них можно случайно поймать строки с числами типа 4040 или 1404. Дальше извлекаем IP-адреса с помощью awk:
grep ' 404 ' access.log | awk '{print $1}'
Получили поток IP-адресов. Теперь нужно их сгруппировать и посчитать. Тут пригодятся стандартные утилиты sort и uniq:
grep ' 404 ' access.log | awk '{print $1}' | sort | uniq -c
Команда sort упорядочивает адреса, а uniq с флагом -c
считает, сколько раз каждый встретился подряд. Осталось отсортировать по количеству:
grep ' 404 ' access.log | awk '{print $1}' | sort | uniq -c | sort -nr
Флаг -n
означает числовую сортировку, -r
- в обратном порядке. Результат выглядит примерно так:
142 203.0.113.45
89 198.51.100.23
34 192.0.2.67
Одна строка в терминале заменила целый скрипт на Python с pandas.
Продвинутые трюки: когда нужно больше
Базовая цепочка команд решает типовые задачи, но иногда требуется что-то хитрее. Допустим, хочешь игнорировать GET-параметры в URL, чтобы /page?id=123
и /page?id=456
считались одной страницей.
Тут поможет sed, который вырежет всё после знака вопроса:
grep ' 404 ' access.log | sed 's/?.*$//' | awk '{print $7}' | sort | uniq -c | sort -nr
Седьмое поле в логе обычно содержит запрошенный URL. Команда sed удаляет знак вопроса и всё, что за ним следует до конца строки.
Другая частая задача - анализ по времени. Скажем, нужны ошибки только за определённый час:
grep '18/Oct/2025:14:' access.log | grep ' 404 ' | awk '{print $1}' | sort | uniq -c | sort -nr
Первый grep фильтрует по метке времени, второй - по коду ошибки. Дальше всё как обычно.
Awk без помощников: всё в одном
Можно обойтись вообще без grep, сделав всю работу внутри awk. Это эффективнее, потому что файл читается один раз, а не прогоняется через несколько утилит:
awk '$9 == 404 {count[$1]++} END {for (ip in count) print count[ip], ip}' access.log | sort -nr
Тут awk сам фильтрует по коду 404, накапливает статистику в массиве и выводит результат. Остаётся только отсортировать.
Такой подход работает быстрее на больших файлах, но менее нагляден для тех, кто только учится. Начинать лучше с простых цепочек, а потом оптимизировать под конкретные задачи.
Когда эти инструменты не подходят
Надо честно признать: grep, sed и awk созданы для построчной обработки простого текста. Если логи в формате JSON или XML, лучше взять специализированные утилиты вроде jq или xmlstarlet. Пытаться парсить сложные вложенные структуры регулярными выражениями - путь к бесконечным ошибкам.
Ещё один момент: эти команды работают построчно и не держат в памяти весь файл. Это плюс для огромных логов, но минус, если нужно анализировать многострочные записи, например стектрейсы исключений. Тут придётся либо предварительно склеивать строки, либо использовать другие инструменты.
Наконец, если анализ логов стал регулярной задачей, стоит подумать о системах централизованного сбора вроде ELK stack или Loki. Но для разовых исследований и быстрого анализа grep с друзьями остаются непревзойдёнными.
Практика делает мастера
Когда я только начинал осваивать эти утилиты, постоянно забывал флаги, путал синтаксис sed и awk, писал регулярные выражения, которые ловили не то. Сейчас пальцы сами набирают нужные команды, потому что через руки прошли сотни разных логов.
Совет простой: не читай только теорию, открой реальный лог и попробуй извлечь из него что-нибудь интересное. Где чаще всего происходят ошибки? Какие страницы самые популярные? Есть ли подозрительная активность с определённых IP? Каждый такой вопрос - повод составить новую цепочку команд.
Со временем заметишь закономерности. Для фильтрации почти всегда нужен grep. Для извлечения полей - awk. Для замен и чисток - sed. А дальше всё собирается в конвейер, где каждая утилита передаёт результат следующей.
Эта модель мышления переносится и на другие задачи. Научившись комбинировать простые инструменты, начинаешь видеть похожие возможности везде. Обработка текстовых отчётов, анализ конфигов, даже работа с CSV-файлами - всюду применим тот же подход.
В Linux нет одной волшебной кнопки, которая решит все проблемы. Зато есть десятки маленьких утилит, каждая из которых делает свою работу идеально. Научись их соединять, и любая задача по обработке текста станет решаемой за минуты. Именно в этом и есть настоящая магия командной строки.