Утилита grep поиск внутри файлов в Linux
Иногда может понадобиться найти файл, в котором содержится определённая строка или найти строку в файле, где есть нужное слово. В Linux для этого существует несколько утилит, одна из самых используемых это grep.
Синтаксис утилиты grep:
grep опции шаблон путь_к_файлу_или_папке
Опцииэто дополнительные параметры, с помощью которых указываются различные настройки поиска и вывода, например количество строк или режим инверсииШаблонэто любая строка или регулярное выражение, по которому будет выполняться поискИмя файла или папкиэто то место, где будет выполняться поиск. Как вы увидите дальше,grepпозволяет искать в нескольких файлах и даже в каталоге, используя рекурсивный режим
Опции
Давайте рассмотрим самые основные опции утилиты, которые помогут более эффективно выполнять поиск текста в файлах grep:
-E, --extended-regexpвключить расширенный режим регулярных выражений (ERE)-F, --fixed-stringsрассматривать шаблон поиска как обычную строку, а не регулярное выражение-G, --basic-regexpинтерпретировать шаблон поиска как базовое регулярное выражение (BRE)-P, --perl-regexpрассматривать шаблон поиска как регулярное выражение Perl-e, --regexpальтернативный способ указать шаблон поиска, опцию можно использовать несколько раз, что позволяет указать несколько шаблонов для поиска файлов, содержащих один из них-f, --fileчитать шаблон поиска из файла-i, --ignore-caseне учитывать регистр символов-v, --invert-matchвывести только те строки, в которых шаблон поиска не найден-w, --word-regexpискать шаблон как слово, отделенное пробелами или другими знаками препинания-x, --line-regexpискать шаблон как целую строку, от начала и до символа перевода строки-cвывести количество найденных строк--colorвключить цветной режим, доступные значения:never, always и auto-L, --files-without-matchвыводить только имена файлов, будут выведены все файлы в которых выполняется поиск-l, --files-with-matchаналогично предыдущему, но будут выведены только файлы, в которых есть хотя бы одно вхождение-m, --max-countостановить поиск после того как будет найдено указанное количество строк-o, --only-matchingотображать только совпавшую часть, вместо отображения всей строки-h, --no-filenameне выводить имя файла-q, --quietне выводить ничего-s, --no-messagesне выводить ошибки чтения файлов-A, --after-contentпоказать вхождение и n строк после него-B, --before-contentпоказать вхождение и n строк перед ним-Cпоказать n строк до и после вхождения-a, --textобрабатывать двоичные файлы как текст--excludeпропустить файлы имена которых соответствуют регулярному выражению--exclude-dirпропустить все файлы в указанной директории-Iпропускать двоичные файлы--includeискать только в файлах, имена которых соответствуют регулярному выражению-rрекурсивный поиск по всем подпапкам-Rрекурсивный поиск включая ссылки
Поиск текста в файле
В первом примере мы будем искать информацию о пользователе root в файле со списком пользователей Linux /etc/passwd. Для этого выполните следующую команду:
grep root /etc/passwd
С помощью опции -i можно указать, что регистр символов учитывать не нужно. Например, давайте найдём все строки содержащие вхождение слова time в том же файле. В этом случае Time, time, TIME и другие вариации слова будут считаться эквивалентными.:
grep -i "time" /etc/passwd
Можно указать несколько условий для поиска, используя опцию -e:
grep -e "root" -e "daemon" /etc/passwd
C помощью опции -n можно выводить номер строки, в которой найдено вхождение:
grep -n 'root' /etc/passwd
Это всё хорошо работает пока ваш поисковый запрос не содержит специальных символов. Например, если вы попытаетесь найти все строки, которые содержат символ [ в файле /etc/grub/00_header, то получите ошибку, что это регулярное выражение не верно. Для того чтобы этого избежать, нужно явно указать, что вы хотите искать строку с помощью опции -F:
grep -F "[" /etc/grub.d/00_header
Фильтрация вывода команды
Для того чтобы отфильтровать вывод другой команды с помощью grep достаточно перенаправить его используя оператор |. А файл для самого grep указывать не надо. Например, для того чтобы найти все процессы gnome можно использовать такую команду:
ps aux | grep "gnome"
Регулярные выражения
Утилита grep поддерживает несколько видов регулярных выражений. Это базовые регулярные выражения BRE, которые используются по умолчанию и расширенные ERE.
Базовые регулярные выражения
Базовые регулярные выражение поддерживает набор символов, позволяющих описать каждый определённый символ в строке:
.любой символ*совпадение элемента ноль или более раз[]помогает задать сразу несколько символов[^]исключает из поиска следующие за^символы или диапазон символов^поиск по совпадению начала строки$получить выборку в которой строки заканчиваются на какое-то выражение
Например, вы можете найти строки, которые начитаются на букву r:
grep "^r" /etc/passwd
Можно найти строки, которые содержат большие буквы:
grep "[A-Z]" /etc/passwd
Можно найти строки, которые заканчиваются на ready в файле /var/log/dmesg:
grep "ready$" /var/log/dmesg
Расширенные регулярные выражения
В дополнение ко всем символам из базового синтаксиса, в расширенном синтаксисе поддерживаются также такие символы:
+одно или больше повторений предыдущего символа?ноль или одно повторение предыдущего символа{n,m}повторение предыдущего символа от n до m раз|позволяет объединять несколько паттернов
Для активации расширенного синтаксиса нужно использовать опцию -E. Например, вместо использования опции -e, можно объединить несколько слов для поиска вот так:
grep -E "root|daemon" /etc/passwd
Вывод контекста
Иногда бывает очень полезно вывести не только саму строку со вхождением, но и строки до и после неё. Например, мы хотим выбрать все ошибки из лог-файла, но знаем, что в следующей строчке после ошибки может содержаться полезная информация, тогда с помощью grep отобразим несколько строк. Ошибки будем искать в /var/log/dmesg по шаблону "Error":
grep -A4 "Error" /var/log/dmesg
Выведет строку с вхождением и 4 строчки после неё.
Эта команда выведет строку со вхождением и 4 строчки до неё:
grep -B4 "Error" /var/log/dmesg
Эта команда выведет по две строки с верху и снизу от вхождения:
grep -C2 "Error" /var/log/dmesg
Рекурсивный поиск
До этого мы рассматривали поиск в определённом файле или выводе команд. Но grep также может выполнить поиск текста в нескольких файлах, размещённых в одном каталоге или подкаталогах. Для этого нужно использовать опцию -r. Например, давайте найдём все файлы, которые содержат строку Kernel в папке /var/log:
grep -r "Kernel" /var/log
Папка с вашими файлами может содержать двоичные файлы, в которых поиск выполнять обычно не надо. Для того чтобы их пропускать используйте опцию -I:
grep -rI "Kernel" /var/log
Некоторые файлы доступны только суперпользователю и для того чтобы выполнять по ним поиск вам нужно запускать grep с помощью sudo. Или же вы можете просто скрыть сообщения об ошибках чтения и пропускать такие файлы с помощью опции -s:
grep -rIs "Kernel" /var/log
Выбор файлов для поиска
С помощью опций --include и --exclude вы можете фильтровать файлы, которые будут принимать участие в поиске. Например, для того чтобы выполнить поиск только по файлам с расширением .log в папке /var/log используйте такую команду:
grep -r --include="*.log" "Kernel" /var/log
А для того чтобы исключить все файлы с расширением .journal надо использовать опцию --exclude:
grep -r --exclude="*.journal" "Kernel" /var/log
Поиск слов
Когда вы ищете строку abc, grep будет выводить также kbabc, abc123, aafrabc32 и тому подобные комбинации. Вы можете заставить утилиту искать по содержимому файлов, которые включают только искомые слова полностью с помощью опции -w:
grep -w "root" /etc/passwd
Количество строк
Утилита grep может сообщить, сколько строк с определенным текстом было найдено файле. Для этого используется опция -c (счетчик):
grep -c 'Kernel' /var/log/dmesg
Инвертированный поиск
Команда grep Linux может быть использована для поиска строк, которые не содержат указанное слово. Например, так можно вывести только те строки, которые не содержат слово nologin:
grep -v nologin /etc/passwd
Вывод имен файлов
Вы можете указать grep выводить только имена файлов, в которых было хотя бы одно вхождение с помощью опции -l. Например, следующая команда выведет все имена файлов из каталога /var/log, при поиске по содержимому которых было обнаружено вхождение Kernel:
grep -lr 'Kernel' /var/log/
Цветной вывод
По умолчанию grep не будет подсвечивать совпадения цветом. Но в большинстве дистрибутивов прописан алиас для grep, который это включает. Однако, когда вы используйте команду c sudo это работать не будет. Для включения подсветки вручную используйте опцию --color со значением always:
grep --color=always root /etc/passwd