Иногда может понадобится найти файл, в котором содержится определённая строка или найти строку в файле, где есть нужное слово. В Linux для этого существует несколько утилит, одна из самых используемых это grep. С её помощью можно искать не только строки в файлах, но и фильтровать вывод команд, и много чего ещё.
В этой инструкции мы рассмотрим что такое команда grep Linux, подробно разберём синтаксис и возможные опции grep, а также приведём несколько примеров работы с этой утилитой.
Что такое grep?
Название команды grep расшифровывается как “search globally for lines matching the regular expression, and print them”. Это одна из самых востребованных команд в терминале Linux, которая входит в состав проекта GNU. До того как появился проект GNU, существовала утилита предшественник grep, тем же названием, которая была разработана в 1973 году Кеном Томпсоном для поиска файлов по содержимому в Unix. А потом уже была разработана свободная утилита с той же функциональностью в рамках GNU.
Grep дает очень много возможностей для фильтрации текста. Вы можете выбирать нужные строки из текстовых файлов, отфильтровать вывод команд, и даже искать файлы в файловой системе, которые содержат определённые строки. Утилита очень популярна, потому что она уже предустановлена прочти во всех дистрибутивах.
Синтаксис 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 – рекурсивный поиск включая ссылки;
Все самые основные опции рассмотрели, теперь давайте перейдём к примерам работы команды grep Linux.
Примеры использования grep
Давайте перейдём к практике. Сначала рассмотрим несколько основных примеров поиска внутри файлов Linux с помощью grep.
1. Поиск текста в файле
В первом примере мы будем искать информацию о пользователе root в файле со списком пользователей Linux /etc/passwd. Для этого выполните следующую команду:
grep root /etc/passwd
В результате вы получите что-то вроде этого:
С помощью опции -i можно указать, что регистр символов учитывать не нужно. Например, давайте найдём все строки содержащие вхождение слова time в том же файле:
grep -i "time" /etc/passwd
В этом случае Time, time, TIME и другие вариации слова будут считаться эквивалентными. Ещё, вы можете указать несколько условий для поиска, используя опцию -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.
2. Фильтрация вывода команды
Для того чтобы отфильтровать вывод другой команды с помощью grep достаточно перенаправить его используя оператор |. А файл для самого grep указывать не надо. Например, для того чтобы найти все процессы gnome можно использовать такую команду:
ps aux | grep "gnome"
В остальном всё работает аналогично.
3. Базовые регулярные выражения
Утилита grep поддерживает несколько видов регулярных выражений. Это базовые регулярные выражения (BRE), которые используются по умолчанию и расширенные (ERE). Базовые регулярные выражение поддерживает набор символов, позволяющих описать каждый определённый символ в строке. Это: ., *, [], [^], ^ и $. Например, вы можете найти строки, которые начитаются на букву r:
grep "^r" /etc/passwd
Или же строки, которые содержат большие буквы:
grep "[A-Z]" /etc/passwd
А так можно найти все строки, которые заканчиваются на ready в файле /var/log/dmesg:
grep "ready$" /var/log/dmesg
Но используя базовый синтаксис вы не можете указать точное количество этих символов.
4. Расширенные регулярные выражения
В дополнение ко всем символам из базового синтаксиса, в расширенном синтаксисе поддерживаются также такие символы:
- + – одно или больше повторений предыдущего символа;
- ? – ноль или одно повторение предыдущего символа;
- {n,m} – повторение предыдущего символа от n до m раз;
- | – позволяет объединять несколько паттернов.
Для активации расширенного синтаксиса нужно использовать опцию -E. Например, вместо использования опции -e, можно объединить несколько слов для поиска вот так:
grep -E "root|daemon" /etc/passwd
Вообще, регулярные выражения grep – это очень обширная тема, в этой статье я лишь показал несколько примеров. Как вы увидели, поиск текста в файлах grep становиться ещё эффективнее. Но на полное объяснение этой темы нужна целая статья, поэтому пока пропустим её и пойдем дальше.
5. Вывод контекста
Иногда бывает очень полезно вывести не только саму строку со вхождением, но и строки до и после неё. Например, мы хотим выбрать все ошибки из лог-файла, но знаем, что в следующей строчке после ошибки может содержаться полезная информация, тогда с помощью grep отобразим несколько строк. Ошибки будем искать в /var/log/dmesg по шаблону “Error”:
grep -A4 "Error" /var/log/dmesg
Выведет строку с вхождением и 4 строчки после неё:
grep -B4 "Error" /var/log/dmesg
Эта команда выведет строку со вхождением и 4 строчки до неё. А следующая выведет по две строки с верху и снизу от вхождения.
grep -C2 "Error" /var/log/dmesg
6. Рекурсивный поиск в grep
До этого мы рассматривали поиск в определённом файле или выводе команд. Но grep также может выполнить поиск текста в нескольких файлах, размещённых в одном каталоге или подкаталогах. Для этого нужно использовать опцию -r. Например, давайте найдём все файлы, которые содержат строку Kernel в папке /var/log:
grep -r "Kernel" /var/log
Папка с вашими файлами может содержать двоичные файлы, в которых поиск выполнять обычно не надо. Для того чтобы их пропускать используйте опцию -I:
grep -rI "Kernel" /var/log
Некоторые файлы доступны только суперпользователю и для того чтобы выполнять по ним поиск вам нужно запускать grep с помощью sudo. Или же вы можете просто скрыть сообщения об ошибках чтения и пропускать такие файлы с помощью опции -s:
grep -rIs "Kernel" /var/log
7. Выбор файлов для поиска
С помощью опций –include и –exclude вы можете фильтровать файлы, которые будут принимать участие в поиске. Например, для того чтобы выполнить поиск только по файлам с расширением .log в папке /var/log используйте такую команду:
grep -r --include="*.log" "Kernel" /var/log
А для того чтобы исключить все файлы с расширением .journal надо использовать опцию –exclude:
grep -r --exclude="*.journal" "Kernel" /var/log
8. Поиск слов в grep
Когда вы ищете строку abc, grep будет выводить также kbabc, abc123, aafrabc32 и тому подобные комбинации. Вы можете заставить утилиту искать по содержимому файлов в Linux строки, которые включают только искомые слова полностью с помощью опции -w. Например:
grep -w "root" /etc/passwd
9. Количество строк
Утилита grep может сообщить, сколько строк с определенным текстом было найдено файле. Для этого используется опция -c (счетчик). Например:
grep -c 'Kernel' /var/log/dmesg
10. Инвертированный поиск
Команда grep Linux может быть использована для поиска строк, которые не содержат указанное слово. Например, так можно вывести только те строки, которые не содержат слово nologin:
grep -v nologin /etc/passwd
11. Вывод имен файлов
Вы можете указать grep выводить только имена файлов, в которых было хотя бы одно вхождение с помощью опции -l. Например, следующая команда выведет все имена файлов из каталога /var/log, при поиске по содержимому которых было обнаружено вхождение Kernel:
grep -lr 'Kernel' /var/log/
12. Цветной вывод
По умолчанию grep не будет подсвечивать совпадения цветом. Но в большинстве дистрибутивов прописан алиас для grep, который это включает. Однако, когда вы используйте команду c sudo это работать не будет. Для включения подсветки вручную используйте опцию –color со значением always:
sudo grep --color=always root /etc/passwd
Получится:
Выводы
Вот и всё. Теперь вы знаете что представляет из себя команда grep Linux, а также как ею пользоваться для поиска файлов и фильтрации вывода команд. При правильном применении эта утилита станет мощным инструментом в ваших руках. Если у вас остались вопросы, пишите в комментариях!
Обнаружили ошибку в тексте? Сообщите мне об этом. Выделите текст с ошибкой и нажмите Ctrl+Enter.
Статья распространяется под лицензией Creative Commons ShareAlike 4.0 при копировании материала ссылка на источник обязательна .
Команда grep
означает «печать глобального регулярного выражения», и это одна из самых мощных и часто используемых команд в Linux.
grep
ищет в одном или нескольких входных файлах строки, соответствующие заданному шаблону, и записывает каждую соответствующую строку в стандартный вывод. Если файлы не указаны, grep
читает из стандартного ввода, который обычно является выводом другой команды.
В этой статье мы покажем вам, как использовать команду grep
на практических примерах и подробных объяснениях наиболее распространенных опций GNU grep
.
Командный синтаксис grep
Синтаксис команды grep
следующий:
grep [OPTIONS] PATTERN [FILE...]
Пункты в квадратных скобках необязательны.
OPTIONS
— Ноль или более вариантов. Grep включает ряд опций , управляющих его поведением.-
PATTERN
— Шаблон поиска. -
FILE
— Ноль или более имен входных файлов.
Чтобы иметь возможность искать файл, пользователь, выполняющий команду, должен иметь доступ для чтения к файлу.
Искать строку в файлах
Наиболее простое использование команды grep
— поиск строки (текста) в файле.
Например, чтобы отобразить все строки, содержащие строку bash
из файла /etc/passwd
, вы должны выполнить следующую команду:
grep bash /etc/passwd
Результат должен выглядеть примерно так:
root:x:0:0:root:/root:/bin/bash
linuxize:x:1000:1000:linuxize:/home/linuxize:/bin/bash
Если в строке есть пробелы, вам нужно заключить ее в одинарные или двойные кавычки:
grep "Gnome Display Manager" /etc/passwd
Инвертировать соответствие (исключить)
Чтобы отобразить строки, не соответствующие шаблону, используйте параметр -v
(или --invert-match
).
Например, чтобы распечатать строки, не содержащие строковый nologin
вы должны использовать:
grep -v nologin /etc/passwd
root:x:0:0:root:/root:/bin/bash
colord:x:124:124::/var/lib/colord:/bin/false
git:x:994:994:git daemon user:/:/usr/bin/git-shell
linuxize:x:1000:1000:linuxize:/home/linuxize:/bin/bash
Использование Grep для фильтрации вывода команды
Вывод команды может быть отфильтрован с помощью grep
через конвейер, и на терминал будут напечатаны только строки, соответствующие заданному шаблону.
Например, чтобы узнать, какие процессы выполняются в вашей системе как пользовательские www-data
вы можете использовать следующую команду ps
:
ps -ef | grep www-data
www-data 18247 12675 4 16:00 ? 00:00:00 php-fpm: pool www
root 18272 17714 0 16:00 pts/0 00:00:00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn www-data
www-data 31147 12770 0 Oct22 ? 00:05:51 nginx: worker process
www-data 31148 12770 0 Oct22 ? 00:00:00 nginx: cache manager process
Вы также можете объединить несколько каналов по команде. Как вы можете видеть в выходных данных выше, также есть строка, содержащая процесс grep
. Если вы не хотите, чтобы эта строка отображалась, передайте результат другому экземпляру grep
как показано ниже.
ps -ef | grep www-data | grep -v grep
www-data 18247 12675 4 16:00 ? 00:00:00 php-fpm: pool www
www-data 31147 12770 0 Oct22 ? 00:05:51 nginx: worker process
www-data 31148 12770 0 Oct22 ? 00:00:00 nginx: cache manager process
Рекурсивный поиск
Для рекурсивного поиска шаблона вызовите grep
с параметром -r
(или --recursive
). Когда используется этот параметр, grep
будет искать все файлы в указанном каталоге, пропуская символические ссылки, которые встречаются рекурсивно.
Чтобы следовать по всем символическим ссылкам , вместо -r
используйте параметр -R
(или --dereference-recursive
).
Вот пример, показывающий, как искать строку linuxize.com
во всех файлах внутри каталога /etc
:
grep -r linuxize.com /etc
Вывод будет включать совпадающие строки с префиксом полного пути к файлу:
/etc/hosts:127.0.0.1 node2.linuxize.com
/etc/nginx/sites-available/linuxize.com: server_name linuxize.com www.linuxize.com;
Если вы используете опцию -R
, grep
будет следовать по всем символическим ссылкам:
grep -R linuxize.com /etc
Обратите внимание на последнюю строку вывода ниже. Эта строка не печатается, когда grep
вызывается с -r
потому что файлы внутри каталога с sites-enabled
Nginx являются символическими ссылками на файлы конфигурации внутри каталога с sites-available
.
/etc/hosts:127.0.0.1 node2.linuxize.com
/etc/nginx/sites-available/linuxize.com: server_name linuxize.com www.linuxize.com;
/etc/nginx/sites-enabled/linuxize.com: server_name linuxize.com www.linuxize.com;
Показать только имя файла
Чтобы подавить вывод grep
по умолчанию и вывести только имена файлов, содержащих совпадающий шаблон, используйте параметр -l
(или --files-with-matches
).
Приведенная ниже команда выполняет поиск по всем файлам, заканчивающимся на .conf
в текущем рабочем каталоге и выводит только имена файлов, содержащих строку linuxize.com
:
grep -l linuxize.com *.conf
Результат будет выглядеть примерно так:
tmux.conf
haproxy.conf
Параметр -l
обычно используется в сочетании с рекурсивным параметром -R
:
grep -Rl linuxize.com /tmp
Поиск без учета регистра
По умолчанию grep
чувствителен к регистру. Это означает, что символы верхнего и нижнего регистра рассматриваются как разные.
Чтобы игнорировать регистр при поиске, вызовите grep
с параметром -i
(или --ignore-case
).
Например, при поиске Zebra
без какой-либо опции следующая команда не покажет никаких результатов, т.е. есть совпадающие строки:
grep Zebra /usr/share/words
Но если вы выполните поиск без учета регистра с использованием параметра -i
, он будет соответствовать как заглавным, так и строчным буквам:
grep -i Zebra /usr/share/words
Указание «Зебра» будет соответствовать «зебре», «ZEbrA» или любой другой комбинации букв верхнего и нижнего регистра для этой строки.
zebra
zebra's
zebras
Искать полные слова
При поиске строки grep
отобразит все строки, в которых строка встроена в строки большего размера.
Например, если вы ищете «gnu», все строки, в которых «gnu» встроено в слова большего размера, такие как «cygnus» или «magnum», будут найдены:
grep gnu /usr/share/words
cygnus
gnu
interregnum
lgnu9d
lignum
magnum
magnuson
sphagnum
wingnut
Чтобы вернуть только те строки, в которых указанная строка представляет собой целое слово (заключенное в символы, отличные от слов), используйте параметр -w
(или --word-regexp
).
Символы слова включают буквенно-цифровые символы ( az
, AZ
и 0-9
) и символы подчеркивания ( _
). Все остальные символы считаются несловесными символами.
Если вы запустите ту же команду, что и выше, включая параметр -w
, команда grep
вернет только те строки, где gnu
включен как отдельное слово.
grep -w gnu /usr/share/words
gnu
Показать номера строк
Параметр -n
(или --line-number
) указывает grep
показывать номер строки, содержащей строку, соответствующую шаблону. Когда используется эта опция, grep
выводит совпадения на стандартный вывод с префиксом номера строки.
Например, чтобы отобразить строки из файла /etc/services
содержащие строку bash
префиксом совпадающего номера строки, вы можете использовать следующую команду:
grep -n 10000 /etc/services
Результат ниже показывает нам, что совпадения находятся в строках 10423 и 10424.
10423:ndmp 10000/tcp
10424:ndmp 10000/udp
Подсчет совпадений
Чтобы вывести количество совпадающих строк в стандартный вывод, используйте параметр -c
(или --count
).
В приведенном ниже примере мы подсчитываем количество учетных записей, в которых в качестве оболочки используется /usr/bin/zsh
.
regular expression
grep -c '/usr/bin/zsh' /etc/passwd
4
Бесшумный режим
-q
(или --quiet
) указывает grep
работать в тихом режиме, чтобы ничего не отображать на стандартном выводе. Если совпадение найдено, команда завершает работу со статусом 0
. Это полезно при использовании grep
в сценариях оболочки, где вы хотите проверить, содержит ли файл строку, и выполнить определенное действие в зависимости от результата.
Вот пример использования grep
в тихом режиме в качестве тестовой команды в операторе if
:
if grep -q PATTERN filename
then
echo pattern found
else
echo pattern not found
fi
Основное регулярное выражение
GNU Grep имеет три набора функций регулярных выражений : базовый, расширенный и Perl-совместимый.
По умолчанию grep
интерпретирует шаблон как базовое регулярное выражение, где все символы, кроме метасимволов, на самом деле являются регулярными выражениями, которые соответствуют друг другу.
Ниже приведен список наиболее часто используемых метасимволов:
-
Используйте символ
^
(каретка) для сопоставления выражения в начале строки. В следующем примере строкаkangaroo
будет соответствовать только в том случае, если она встречается в самом начале строки.grep "^kangaroo" file.txt
-
Используйте символ
$
(доллар), чтобы найти выражение в конце строки. В следующем примере строкаkangaroo
будет соответствовать только в том случае, если она встречается в самом конце строки.grep "kangaroo$" file.txt
-
Используйте расширение
.
(точка) символ, соответствующий любому одиночному символу. Например, чтобы сопоставить все, что начинается сkan
затем имеет два символа и заканчивается строкойroo
, вы можете использовать следующий шаблон:grep "kan..roo" file.txt
-
Используйте
[ ]
(скобки) для соответствия любому одиночному символу, заключенному в квадратные скобки. Например, найдите строки, содержащиеaccept
или «accent
, вы можете использовать следующий шаблон:grep "acce[np]t" file.txt
-
Используйте
[^ ]
для соответствия любому одиночному символу, не заключенному в квадратные скобки. Следующий шаблон будет соответствовать любой комбинации строк, содержащихco(any_letter_except_l)a
, напримерcoca
,cobalt
и т. Д., Но не будет соответствовать строкам, содержащимcola
,grep "co[^l]a" file.txt
Чтобы избежать специального значения следующего символа, используйте символ (обратная косая черта).
Расширенные регулярные выражения
Чтобы интерпретировать шаблон как расширенное регулярное выражение, используйте параметр -E
(или --extended-regexp
). Расширенные регулярные выражения включают в себя все основные метасимволы, а также дополнительные метасимволы для создания более сложных и мощных шаблонов поиска. Вот несколько примеров:
-
Сопоставьте и извлеките все адреса электронной почты из данного файла:
grep -E -o "b[A-Za-z0-9._%+-][email protected][A-Za-z0-9.-]+.[A-Za-z]{2,6}b" file.txt
-
Сопоставьте и извлеките все действительные IP-адреса из данного файла:
grep -E -o '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)' file.txt
Параметр -o
используется для печати только соответствующей строки.
Поиск нескольких строк (шаблонов)
Два или более шаблонов поиска можно объединить с помощью оператора ИЛИ |
.
По умолчанию grep
интерпретирует шаблон как базовое регулярное выражение, в котором метасимволы, такие как |
теряют свое особое значение, и необходимо использовать их версии с обратной косой чертой.
В приведенном ниже примере мы ищем все вхождения слов fatal
, error
и critical
в файле ошибок журнала Nginx :
grep 'fatal|error|critical' /var/log/nginx/error.log
Если вы используете опцию расширенного регулярного выражения -E
, то оператор |
не следует экранировать, как показано ниже:
grep -E 'fatal|error|critical' /var/log/nginx/error.log
Строки печати перед матчем
Чтобы напечатать определенное количество строк перед совпадающими строками, используйте параметр -B
(или --before-context
).
Например, чтобы отобразить пять строк ведущего контекста перед совпадающими строками, вы должны использовать следующую команду:
grep -B 5 root /etc/passwd
Печатать строки после матча
Чтобы напечатать определенное количество строк после совпадающих строк, используйте параметр -A
(или --after-context
).
Например, чтобы отобразить пять строк конечного контекста после совпадающих строк, вы должны использовать следующую команду:
grep -A 5 root /etc/passwd
Выводы
Команда grep
позволяет искать шаблон внутри файлов. Если совпадение найдено, grep печатает строки, содержащие указанный шаблон.
Подробнее о Grep можно узнать на странице руководства пользователя Grep .
Если у вас есть какие-либо вопросы или отзывы, не стесняйтесь оставлять комментарии.
Делайте так:
grep -rnw '/путь/к/папке/с/файлами' -e "шаблон"
-r
или-R
– рекурсивный поиск.-n
– вывод номера строки.-w
– только целые слова.-l
(нижний регистр отL
) – вывод имени файла, где было совпадение.
Эффективности добавят следующие флаги:
-
--exclude
– Шаблон для исключения файлов, например: поиск везде, кроме файлов с расширением.o
:grep --exclude=*.o -rnw '/путь/к/папке/с/файлами' -e "шаблон"
-
--include
– Поиск только в определённых файлах, например: только в файлах с расширениями.h
и.c
:grep --include=*.{c,h} -rnw '/путь/к/папке/с/файлами' -e "шаблон"
-
--exclude-dir
и--include-dir
– то же, только для выборки директорий, например: исключить папкиодин
,two
и любые, начинающиеся наа
:grep --exclude-dir={один,two,а*} -rnw '/путь/к/папке/с/файлами' -e "шаблон"
Это отлично работает для подобных целей, остальные настройки для grep
можно узнать, выполнив man grep
.
При формировании ответа использовался ответ на вопрос «How do I find all files containing specific text on Linux?» от участника @rakib.
Перевод публикуется с сокращениями, автор оригинальной статьи Abhishek
Nair.
Название утилиты расшифровывается как Globally search for a REgular expression and Print matching lines. Grep в основном ищет заданный шаблон или регулярное выражение из стандартного ввода или файла и печатает соответствующие заданным критериям строки. Он часто используется для фильтрации ненужных деталей при выводе только необходимой информации из больших файлов журналов.
Мощь регулярных выражений в сочетании с поддерживаемыми опциями в grep делает это возможным.
Начнем!
Синтаксис команды
Grep ожидает шаблон и
необязательные аргументы вместе со списком файлов, если они используются без
конвейера.
$ grep [options] pattern [files]
Пример:
$ grep my file.txt
my_file
$
1. Поиск в нескольких файлах
Grep позволяет искать
заданный шаблон не только в одном, но и в нескольких файлах с помощью масок (например, знака «*»):
$ sudo grep -i err /var/log/messages*
Вывод:
$ sudo grep err /var/log/messages*
/var/log/messages:Dec 28 10:36:52 centos7vm kernel: ACPI: Using IOAPIC for interrupt routing
/var/log/messages:Dec 28 10:36:52 centos7vm kernel: ACPI: PCI Interrupt Link [LNKA] (IRQs 5 9 10 *11)
/var/log/messages:Dec 28 10:36:52 centos7vm kernel: ACPI: PCI Interrupt Link [LNKB] (IRQs 5 9 *10 11)
/var/log/messages:Dec 28 10:36:52 centos7vm kernel: ACPI: PCI Interrupt Link [LNKC] (IRQs 5 *9 10 11)
/var/log/messages:Dec 28 10:36:52 centos7vm kernel: ACPI: PCI Interrupt Link [LNKD] (IRQs 5 9 10 *11)
/var/log/messages-20201225:Dec 23 23:01:00 centos7vm kernel: ACPI: Using IOAPIC for interrupt routing
/var/log/messages-20201225:Dec 23 23:01:00 centos7vm kernel: ACPI: PCI Interrupt Link [LNKA] (IRQs 5 9 10 *11)
/var/log/messages-20201225:Dec 23 23:01:00 centos7vm kernel: ACPI: PCI Interrupt Link [LNKB] (IRQs 5 9 *10 11)
/var/log/messages-20201225:Dec 23 23:01:00 centos7vm kernel: ACPI: PCI Interrupt Link [LNKC] (IRQs 5 *9 10 11)
/var/log/messages-20201225:Dec 23 23:01:00 centos7vm kernel: ACPI: PCI Interrupt Link [LNKD] (IRQs 5 9 10 *11)
/var/log/messages-20201225:Dec 23 23:01:00 centos7vm kernel: BERT: Boot Error Record Table support is disabled. Enable it by using bert_enable as kernel parameter.
/var/log/messages-20201227:Dec 27 19:11:18 centos7vm kernel: ACPI: PCI Interrupt Link [LNKA] (IRQs 5 9 10 *11)
/var/log/messages-20201227:Dec 27 19:11:18 centos7vm kernel: ACPI: PCI Interrupt Link [LNKB] (IRQs 5 9 *10 11)
/var/log/messages-20201227:Dec 27 19:11:18 centos7vm kernel: ACPI: PCI Interrupt Link [LNKC] (IRQs 5 *9 10 11)
/var/log/messages-20201227:Dec 27 19:11:18 centos7vm kernel: ACPI: PCI Interrupt Link [LNKD] (IRQs 5 9 10 *11)
/var/log/messages-20201227:Dec 27 19:11:18 centos7vm kernel: BERT: Boot Error Record Table support is disabled. Enable it by using bert_enable as kernel parameter.
/var/log/messages-20201227:Dec 27 19:11:21 centos7vm kernel: [drm:vmw_host_log [vmwgfx]] *ERROR* Failed to send host log message.
/var/log/messages-20201227:Dec 27 19:11:21 centos7vm kernel: [drm:vmw_host_log [vmwgfx]] *ERROR* Failed to send host log message.
$
Из приведенного вывода
можно заметить, что grep печатает имя файла перед соответствующей строкой, чтобы
указать местонахождение шаблона.
2. Поиск без учета регистра
Grep предлагает искать
паттерн, не глядя на его регистр. Используйте флаг -i, чтобы утилита игнорировала регистр:
$ grep -i [pattern] [file]
Вывод:
$ grep -i it text_file.txt
This is a sample text file. It contains
functionality. You can always use grep with any
kind of data but it works best with text data.
It supports numbers like 1, 2, 3 etc. as well as
This is a sample text file. It's repeated two times.
$
3. Поиск всего слова
Зачастую вместо
частичного совпадения необходимо полное соответствие поисковому слову. Это можно
сделать, используя флаг -w:
$ grep -w [pattern] [file]
Вывод:
$ grep -w is text_file.txt
This is a sample text file. It contains
This is a sample text file. It's repeated two times.
$
4. Проверка количества совпадений
Иногда вместо
фактического совпадения со строкой нам необходимо количество успешных
совпадений, найденных grep. Этот результат можно получить, используя опцию -c:
$ grep -c [pattern] [file]
Вывод:
$ grep -c is text_file.txt
2
$
5. Поиск в подкаталогах
Часто требуется выполнить
поиск файлов не только в текущем рабочем каталоге, но и в подкаталогах. Grep позволяет это сделать с помощью флага -r:
$ grep -r [pattern] *
Вывод:
$ grep -r Hello *
dir1/file1.txt:Hello One
dir1/file2.txt:Hello Two
dir1/file3.txt:Hello Three
$
Как можно заметить,
grep проходит через каждый подкаталог внутри текущего каталога и перечисляет
файлы и строки, в которых найдено совпадение.
6. Инверсивный поиск
Если вы хотите найти
что-то несоответствующее заданному шаблону, grep и это умеет при помощи флага -v:
$ grep -v [pattern] [file]
Вывод:
$ grep This text_file.txt
This is a sample text file. It contains
This is a sample text file. It's repeated two times.
$ grep -v This text_file.txt
several lines to be used as part of testing grep
functionality. You can always use grep with any
kind of data but it works best with text data.
It supports numbers like 1, 2, 3 etc. as well as
alphabets and special characters like - + * # etc.
$
Можно сравнить вывод
команды grep по одному и тому же шаблону и файлу с флагом -v или без него. С флагом печатается каждая строка, которая
не соответствует шаблону.
7. Печать номеров строк
Если хотите напечатать
номера найденных строк, чтобы узнать их позицию в файле, используйте
опцию -n:
$ grep -n [pattern] [file]
Вывод:
$ grep -n This text_file.txt
1:This is a sample text file. It contains
7:This is a sample text file. It's repeated two times.
$
8. Ограниченный вывод
Для больших файлов вывод может быть огромным и тогда вам понадобится
фиксированное количество строк вместо всей простыни. Можно использовать –m[num]:
$ grep -m[num] [pattern] [file]
Обратите внимание, как
использование флага влияет на вывод для того же набора условий:
$ grep It text_file.txt
This is a sample text file. It contains
It supports numbers like 1, 2, 3 etc. as well as
This is a sample text file. It's repeated two times.
$ grep -m2 It text_file.txt
This is a sample text file. It contains
It supports numbers like 1, 2, 3 etc. as well as
$
9. Отображение дополнительных строк
Иногда необходимо
вывести не только строки по некоторому шаблону, но и дополнительные строки выше
или ниже найденных для понимания контекста. Можно напечатать строку выше, ниже или оба варианта, используя флаги -A, -B или -C со значением num (количество дополнительных строк, которые будут напечатаны). Это применимо ко всем совпадениям, которые grep находит в указанном файле или в списке файлов.
$ grep -A[num] [pattern] [file]
или
$ grep -B[num] [pattern] [file]
или
$ grep -C[num] [pattern] [file]
Ниже показан обычный
вывод grep, а также вывод с флагами. Обратите внимание, как grep интерпретирует флаги и их значения, а также
изменения в соответствующих выходных данных:
- с флагом –A1 выведется 1 строка, следующая за основной;
- –B1 напечатает 1 строку перед основной;
- –C1 выведет по одной строке снизу и сверху.
$ grep numbers text_file.txt
It supports numbers like 1, 2, 3 etc. as well as
$ grep -A1 numbers text_file.txt
It supports numbers like 1, 2, 3 etc. as well as
alphabets and special characters like - + * # etc.
$ grep -B1 numbers text_file.txt
kind of data but it works best with text data.
It supports numbers like 1, 2, 3 etc. as well as
$ grep -C1 numbers text_file.txt
kind of data but it works best with text data.
It supports numbers like 1, 2, 3 etc. as well as
alphabets and special characters like - + * # etc.
$
10. Список имен файлов
Чтобы напечатать только
имя файлов, в которых найден шаблон, используйте флаг -l:
$ grep -l [pattern] [file]
Вывод:
$ grep -l su *.txt
file.txt
text_file.txt
$
11. Точный вывод строк
Если необходимо
напечатать строки, которые точно соответствуют заданному шаблону, а не какой-то
его части, применяйте в команде ключ -x:
$ grep -x [pattern] [file]
В приведенном ниже
примере file.txt содержится слово «support», а строки без точного совпадения
игнорируются.
$ grep -x support *.txt
file.txt:support
$
12. Совпадение по началу строки
Используя регулярные
выражения, можно найти начало строки:
$ grep [options] "^[string]" [file]
Пример:
$ grep It text_file.txt
This is a sample text file. It contains
It supports numbers like 1, 2, 3 etc. as well as
This is a sample text file. It's repeated two times.
$ grep ^It text_file.txt
It supports numbers like 1, 2, 3 etc. as well as
$
Обратите внимание, как
использование символа «^» изменяет выходные данные. Знак «^» указывает начало
строки, т.е. ^It соответствует любой
строке, начинающейся со слова It.
Заключение в кавычки может помочь, когда шаблон содержит пробелы и т. д.
13. Совпадение по концу строки
Эта полезная регулярка
способна помочь найти по шаблону конец строки:
$ grep [options] "[string]$" [file]
Пример:
$ grep "." text_file.txt
This is a sample text file. It contains
functionality. You can always use grep with any
kind of data but it works best with text data.
It supports numbers like 1, 2, 3 etc. as well as
alphabets and special characters like - + * # etc.
This is a sample text file. It's repeated two times.
$ grep ".$" text_file.txt
kind of data but it works best with text data.
alphabets and special characters like - + * # etc.
This is a sample text file. It's repeated two times.
$
Обратите внимание, как
меняется вывод, когда мы сопоставляем символ «.» и когда используем «$», чтобы сообщить утилите о строках, заканчивающихся на «.» (без тех, которые могут содержать
символ посередине).
14. Файл шаблонов
Если у вас есть некий
список часто используемых шаблонов, укажите его в файле и используйте флаг -f. Файл должен содержать по одному шаблону на строку.
$ grep -f [pattern_file] [file_to_match]
В примере мы создали файл
шаблонов pattern.txt с таким содержанием:
$ cat pattern.txt
This
It
$
Чтобы это использовать,
применяйте ключ -f:
$ grep -f pattern.txt text_file.txt
This is a sample text file. It contains
It supports numbers like 1, 2, 3 etc. as well as
This is a sample text file. It's repeated two times.
$
15. Указание нескольких шаблонов
Grep позволяет указать
несколько шаблонов с помощью -e:
$ grep -e [pattern1] -e [pattern2] -e [pattern3]...[file]
Пример:
$ grep -e is -e It -e to text_file.txt
This is a sample text file. It contains
several lines to be used as part of testing grep
It supports numbers like 1, 2, 3 etc. as well as
This is a sample text file. It's repeated two times.
$
Grep поддерживает
расширенные регулярные выражения или ERE (похожие на egrep) с использованием флага -E.
Использование ERE имеет
преимущество, когда вы хотите рассматривать мета-символы как есть и не хотите
заменять их строками. Использование -E
с grep эквивалентно команде egrep.
$ grep -E '[Extended RegEx]' [file]
Вот одно из применений
ERE, когда необходимо вывести строки, например, из больших конфигурационных
файлов. Здесь использовался флаг -v,
чтобы не печатать строки, соответствующие шаблону ^(#|$).
$ sudo grep -vE '^(#|$)' /etc/ssh/sshd_config
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
SyslogFacility AUTHPRIV
AuthorizedKeysFile .ssh/authorized_keys
PasswordAuthentication yes
ChallengeResponseAuthentication no
GSSAPIAuthentication yes
GSSAPICleanupCredentials no
UsePAM yes
X11Forwarding yes
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
AcceptEnv XMODIFIERS
Subsystem sftp /usr/libexec/openssh/sftp-server
$
Заключение
Приведенные выше
примеры – лишь верхушка айсберга. Grep поддерживает
целый ряд опций и может оказаться полезным инструментом в руках специалиста,
который способен эффективно его использовать. Мы можем не только взять на вооружение приведенные выше примеры, но и комбинировать их, чтобы получить требуемый
результат в различных условиях.
Для дальнейшего
изучения утилиты и расширения кругозора стоит почитать мануал, выполнив в
терминале команду man grep, или
посетить страницу с официальной документацией.
Дополнительные материалы:
- Настольные книги по Linux на русском языке
- 20 лучших инструментов для хакинга на Kali Linux
- 6 команд терминала и пара комбинаций, полезных для начинающих разработчиков
- 10 лучших видеокурсов для изучения Linux
- 7 книг по UNIX/Linux
Необходимо в каталоге найти файлы содержащие определенную фразу. Как это сделать? Думаю, многие не раз сталкивались с подобной проблемой, как необходимость найти в папке с файлами (а порой и подпапками, в которых тоже хорошо бы поискать) файл, зная кусочек его текста (ну, или догадываясь о нем). Я тоже много раз спотыкался об эту нужда и вот, наконец, собрался и написал небольшой скрипт на bash, выполняющий эту задачу. Не самой общераспространенной задачей, но всё же имеющей место быть, является поиск исполняемого файла программы. Она воспринимает в качестве параметра имя программы, а после выполнения выводит в терминал список с расположением одновременных файлов. Иногда может понадобится найти файл, в котором содержится определённая строчка или найти строку в файле, где есть нужное слово. В Linux всё это делается с помощью одной весьма простой, но в то же время мощной утилиты grep. С её помощью можно искать не только строчки в файлах, но и фильтровать вывод команд, и много чего ещё.
Содержание статьи
- 1 Linux поиск по содержимому файлов командой grep
- 2 Linux поиск по содержимому файлов командой find
- 3 Linux поиск по содержимому файлов командой which
- 4 Linux поиск по содержимому файлов командой locate
Linux поиск по содержимому файлов командой grep
Часто возникают ситуации, что нужно найти какой-нибудь текст, но вы не помните, в каком файле/файлах он содержится. Секрет популярности — её мощь, она отдает возможность пользователям сортировать и фильтровать текст на основе сложных правил.
Команда grep (расшифровывается как global regular expression print) — одна из самых востребованных команд в терминале Linux, которая входит в состав проекта GNU.
В этом варианте для поиска по содержимому файлов в каталоге можно использовать утилиту grep:
grep -r -n «text» /path
grep -r "Строчка для поиска"
grep -rl $'xEFxBBxBF'
где:
-n показывает строку, где был найден фрагмент;
-r осуществляет розыск рекурсивно, в файлах в самом каталоге /path и в его подкаталогах;
Также можно приплюсовать опцию -C 3, чтобы видеть +- 3 строки вокруг (выше и ниже от найденной).
Дабы найти файл по его содержимому во всех Linux — подобных ОС, достаточно использовать утилиту find.
Linux поиск по содержимому файлов командой find
Своего рода швейцарским ножом в розыске файлов является команда find. Отметим, что она имеет множество опций, которые смогут кардинально изменять механизм поиска. Мы изложим лишь основные принципы, а с остальными способностями ознакомьтесь в справке по команде. Базовый принцип использования find состоит в указании папки поиска и опций. Например, выражение «find ~/ -name *.cpp» осуществит поиск файлов, имеющих продолжение «cpp» по всем каталогам, находящимся в личной директории пользователя.
/usr/bin/find /папка -type f -exec grep -H 'строчка для поиска' {} ;
Значение, указанное после опции -name, задает шаблон соотношения имени файла. Вы можете использовать опцию -type для указания типа файла, где в свойстве значений нужно использовать специальные буквы: d — директория, f — файл, l — символическая ссылка и т. д. Функции -user, -group и -size также довольно полезны. Их значениями являются имя пользователя, имя категории и размер файла в байтах.
find /var/www/ -name "file.conf"
find /var/www/ -name "*.conf"
С поддержкою опции -exec каждому файлу, предназначенному для установки соответствия, можно добавить случайную обработку. Таким образом, появляется возможность осуществления поиска, как по имени файла, так и по охватываемому. Ниже приводится пример комбинирования команды find и grep за счет использования функции -exec.
find ~/ -name *.cpp
find ~/ -name *.cpp -user 'my-username' -group 'my-group'
find ~/ -name '*.config' -type f -exec grep 'user' {} ;
find /home/ ( -name "*.php" -or -name "*.html" -or -name "*.js" )
-exec grep -lHEi $'xEFxBBxBF' {} ;
А возможно и еще проще
Linux поиск по содержимому файлов командой which
Бригада which ищет только те файлы, у которых есть право на выполнение как программы. Розыск осуществляется по директориям, заданным в переменной окружения PATH. Содержимое переменной PATH сможет отличаться для различных пользователей. Чтобы охватить как можно большее количество системных директория, необходимо войти в систему под учетной записью администратора.
which cat
/bin/cat
which docker-stack
/home/username/.local/bin/docker-stack
Linux поиск по содержимому файлов командой locate
Поиск, производимый командой locate весьма быстр. Однако учитывайте тот факт, что системная база данных может быть не живой на момент осуществления операции. Механизм сканирования файловой системы, время его проведения и вобщем наличие такого инструмента может разниться в различных дистрибутивах Linux. Команда locate может быть полезна лишь при поиске файла по его имени. Однако для проверки текстового содержимого документов на вступление искомых данных нужно использовать другой инструмент.
Команда locate представляется альтернативой для find.
Данная команда, как правило, работает быстрее и может с легкостью производить поиск (в широком смысле — стремление добиться чего-либо, найти что-либо; действия субъекта, направленные на получение нового или утерянного (забытого): новой информации (поиск информации), данных,) по всей файловой системы. Linux имеет специальную команду grep, какая принимает шаблон для поиска и имя файла (именованная область данных на носителе информации). В случае нахождения совпадений, они будут выведены в терминал. В всеобщем виде выражение можно составить как «grep шаблон_поиска имя_файла». Чтобы отыскать файлы с помощью команды locate, просто используйте следующий синтаксис:
locate query
К образцу, чтобы возвращать только файлы, содержащие сам запрос, вместо того чтобы вводить каждый файл, который содержит запрос в ведущих к нему каталогах, можно утилизировать флаг –b (чтоб искать только basename, базовое имя файла):
locate -b query
Команды find и locate – отличные инструменты для поиска файлов в UNIX‐подобных операционных системах. Любая из этих утилит имеет свои преимущества. Мы рассмотрели использование команд для поиска и фильтрации вывода бригад в операционной системе Linux. При правильном применении эта утилита станет мощным инструментом в ваших руках. Несмотря на то, что команды find и locate сами по себе очень мощны, их действие возможно расширить, комбинируя их с другими командами. Научившись работать с find и locate, попробуйте чистить их результаты при помощи команд wc, sort и grep.