Когда на сервере накапливаются гигабайты логов, десятки конфигурационных файлов и сотни строк вывода команд, найти нужную информацию вручную практически невозможно. Здесь на помощь приходит grep – одна из самых полезных утилит в Linux. grep позволяет за доли секунды найти строки, содержащие нужный текст или соответствующие заданному шаблону.
Что такое grep
grep – это консольная утилита для поиска строк по заданному образцу. Она просматривает текст построчно и выводит только те строки, которые соответствуют шаблону.
Название часто расшифровывают как global regular expression print, но исторически оно произошло от команды редактора ed: g/re/p (g – globally, re – regular expression, p – print). Имя утилиты – это и есть та самая команда, вынесенная в отдельную программу.
Утилита работает в трех основных режимах:
- поиск в одном или нескольких файлах;
- поиск в потоке данных, который передается через конвейер (pipe) от другой команды;
- рекурсивный поиск по всем файлам внутри директории.
Команда grep входит в стандартный набор утилит любого дистрибутива Linux, поэтому устанавливать ее отдельно не нужно. Проверить наличие и версию можно так:
grep --versionСинтаксис команды grep
Общая структура команды выглядит следующим образом:
grep [опции] "шаблон" [файл...]Где:
опции– необязательные флаги, которые меняют поведение поиска;шаблон– строка или регулярное выражение, которое необходимо найти;файл– один или несколько файлов, в которых выполняется поиск с помощьюgrep.
Шаблон рекомендуется заключать в кавычки. Это обязательно, если он содержит пробелы или специальные символы.
Базовые примеры использования
Самый простой случай – найти строки со словом error в файле лога:
grep "error" access.loggrep выведет все строки, в которых встречается error, подсвечивая совпадения (если включена цветная подсветка).
С помощью grep поиск можно вести сразу по нескольким файлам, перечислив их через пробел:
grep "error" access.log error.logВ этом случае перед каждой найденной строкой grep укажет имя файла, в котором она найдена.
Часто grep используют в связке с другими командами через конвейер. Например, чтобы отфильтровать вывод команды и оставить только строки с процессом nginx:
ps aux | grep nginxЗдесь grep получает данные не из файла, а из вывода предыдущей команды.
В выводе ps aux | grep nginx почти всегда оказывается лишняя строка – сам процесс grep nginx, который в момент поиска тоже виден в списке процессов. Чтобы исключить его, применяют небольшую хитрость с символьным классом:
ps aux | grep [n]ginxШаблон [n]ginx совпадает со строкой nginx, но сама команда в списке процессов выглядит как grep [n]ginx и под этот шаблон уже не подходит. Как альтернатива – специализированная утилита pgrep nginx, которая ищет процессы по имени и этой проблемы лишена.
Основные опции grep
Возможности grep раскрываются именно через опции. Разберем те, что используются чаще всего:
- игнорирование регистра:
-i
По умолчанию grep различает заглавные и строчные буквы. Флаг -i отключает чувствительность к регистру, и тогда Error, ERROR и error будут считаться совпадениями:
grep -i "error" access.log- инверсия поиска:
-v
Флаг -v выводит строки, которые не содержат шаблон. Удобно, когда нужно исключить лишнее. Например, показать все строки конфига, кроме пустых и закомментированных:
grep -vE "^#|^$" nginx.conf- номера строк:
-n
Опция -n добавляет к каждой найденной строке ее номер в файле. Это упрощает дальнейшую работу с файлом:
grep -n "server_name" nginx.conf- строки контекста:
-A,-B,-C
При разборе логов часто важна не только сама совпавшая строка, но и то, что происходило рядом с ней. Для этого есть три опции:
-A N(after) – показатьNстрок после совпадения;-B N(before) – показатьNстрок до совпадения;-C N(context) – показатьNстрок до и после совпадения.
Например, вывести строку с ошибкой и три следующие за ней строки – чтобы увидеть, что произошло после сбоя:
grep -A3 "error" app.logПоказать совпадение вместе с двумя строками перед ним:
grep -B2 "error" app.logА -C покажет окружение с обеих сторон сразу:
grep -C3 "error" app.logЕсли в файле несколько совпадений, grep отделяет их блоки строкой с --.
- подсчет совпадений:
-c
Если важно не содержимое, а количество строк с совпадением, используйте -c:
grep -c "404" access.logКоманда вернет только число строк, в которых встретился код 404.
- вывод только совпавшей части:
-o
По умолчанию grep выводит строку целиком, даже если шаблон совпал лишь с ее частью. Флаг -o оставляет в выводе только сам фрагмент, совпавший с шаблоном, а каждое совпадение печатается на отдельной строке. Это удобно, когда нужно извлечь конкретные данные, а не строки целиком – например, вытащить из лога все IP-адреса в начале строк:
grep -oE "^[0-9.]+" access.log- список файлов с совпадениями:
-l
Флаг -l выводит не сами строки, а имена файлов, в которых есть хотя бы одно совпадение:
grep -l "password" *.phpЭто удобно, когда нужно понять, в каких файлах встречается определенный текст.
- рекурсивный поиск:
-rи-R
Опция -r запускает поиск по всем файлам в указанной директории и во всех вложенных папках:
grep -r "TODO" /var/www/site/Разница между -r и -R касается обработки символических ссылок при рекурсивном обходе. Если grep натыкается на symlink внутри подкаталогов, то -r такие ссылки игнорирует, а -R по ним переходит. При этом по ссылке, явно указанной в самой команде, перейдут оба варианта.
- поиск целых слов:
-w
По умолчанию команда Linux grep находит шаблон даже как часть другого слова. Например, поиск cat выдаст и category, и concatenate. Флаг -w ограничивает поиск целыми словами:
grep -w "cat" file.txt- совпадение по всей строке:
-x
Если -w ограничивает совпадение целым словом, то -x требует, чтобы шаблону соответствовала вся строка целиком. Это удобно при точечной проверке конфигов или списков:
grep -x "127.0.0.1 localhost" /etc/hosts- поиск по нескольким шаблонам сразу:
-e
Когда нужно искать несколько разных строк за один проход, необязательно собирать сложное регулярное выражение. Можно перечислить шаблоны через флаг -e:
grep -e "404" -e "500" access.log- поиск по фиксированной строке:
-F
По умолчанию grep трактует шаблон как регулярное выражение, поэтому символы ., *, [, $ и другие имеют специальное значение. Если же нужно найти строку буквально, со всеми спецсимволами как есть, используйте флаг -F (fixed strings):
grep -F "192.168.0.1" access.logЗдесь точки будут восприняты как обычные точки, а не как «любой символ». Это избавляет от необходимости экранировать каждый спецсимвол и заметно ускоряет поиск на больших файлах. Раньше для этого существовала отдельная команда fgrep, но сейчас она считается устаревшей – рекомендуется применять grep -F.
Регулярные выражения в grep
Регулярные выражения в grep позволяют описывать не точный текст, а шаблон, которому должны соответствовать строки. grep работает с тремя типами регулярных выражений.
Базовые регулярные выражения (BRE)
Это режим по умолчанию. Основные метасимволы:
^– начало строки;$– конец строки;.– любой одиночный символ;*– повторение предыдущего символа ноль или более раз;[...]– любой символ из указанного набора.
Несколько примеров:
- Найти строки, начинающиеся со слова
Error:
grep "^Error" error.log- Найти строки, заканчивающиеся на
;:
grep ";$" nginx.conf- Найти пустые строки:
grep "^$" file.txtРасширенные регулярные выражения (ERE)
В базовом режиме символы +, ?, {}, | и () нужно экранировать обратным слешем. Чтобы этого избежать, используйте флаг -E. Он включает расширенный синтаксис. Раньше для этого существовала отдельная команда egrep, но сейчас рекомендуется применять именно grep -E.
Дополнительные возможности ERE:
+– повторение один или более раз;?– ноль или одно повторение;{n,m}– отnдоmповторений;|– логическое «или»;()– группировка.
Например, найти строки с кодами ошибок 404 или 500:
grep -E "404|500" access.logНайти слова color и colour одновременно:
grep -E "colou?r" file.txtPerl-совместимые регулярные выражения (PCRE)
Флаг -P включает наиболее мощный синтаксис регулярных выражений, совместимый с языком Perl. Он поддерживает такие конструкции, как \d (цифра), \w (буква, цифра или подчеркивание), \s (пробельный символ), а также «ленивые» квантификаторы и опережающие проверки.
Например, извлечь все email-адреса:
grep -oP "[\w.-]+@[\w.-]+\.\w+" file.txtСтоит учитывать, что режим -P поддерживается не во всех системах, так как он опирается на отдельную библиотеку PCRE.
Объединение grep в цепочки
grep можно вызывать несколько раз подряд, последовательно сужая результат. Это работает благодаря конвейеру: вывод одной команды grep передается на вход следующей.
Например, найти в логе строки с кодом 404, относящиеся к запросам изображений в формате PNG:
grep "404" access.log | grep "\.png"Сначала первый grep отбирает строки с 404, а затем второй из них оставляет только те, что содержат .png. Такой подход часто оказывается проще, чем составлять одно сложное регулярное выражение.
Если возникнут вопросы о работе VPS-серверов, напишите нам, пожалуйста, тикет из панели управления аккаунта (раздел «Помощь и поддержка»), а если вы захотите обсудить наши продукты с коллегами по цеху и сотрудниками Beget – ждем вас в нашем сообществе в Telegram.