```sh # Найти точное соответствие Для того чтобы искать соответствия только целым словам, используйте флаг "-w": ls 'test script.sh' test test_1 test_2 ls | grep -w test test script.sh test # Аналогичного результата можно добиться через регулярное выражение: ls | grep "\" test script.sh test # "\<" — начало слова. # "test" — искомый текст. # "\>" — конец слова. # Угловые скобки должны экранироваться, иначе они будут интерпретироваться как простые символы. # Игнорировать регистр # По умолчанию, grep чувствительна к регистру, что немного мешает поиску. Проблема решается путем добавления ключа "-i" к команде: ls | grep -i new newFile NewFile #Вывод файлов с совпадениями. Используйте параметр "-l", чтобы вывести не сами строки, а только пути к файлам, в которых они содержатся: grep -r -l "libnma" /usr/share /usr/share/doc/libnma-gtk4-0/copyright # Параметр "-r" отвечает за рекурсивный поиск - grep прошерстит не только 1 уровень каталога, а пойдет вглубь. # Поиск по нескольким параметрам. Для того, чтобы передать команде несколько вводных данных для определения совпадений, используется флаг "-e" перед каждым объектом поиска: ls | grep -i -e new -e old NewFile newFile oldFile # Эту команду система понимает, как "или-или" и выводит все вхождения указанных слов. # Использование регулярных выражений. # Настоящая сила grep проявляется, когда вы переходите от сопоставления простых строк к сопоставлению шаблонов - регулярных выражений. # Выражения бывают 2 типов: basic и extended. Одна из особенностей второго типа заключается в том, что некоторые символы требуют экранирования для сохранности фич: ?, +, {, |, (, ), <, >. # Но можно обойтись просто добавлением флага "-E": ls | grep -E "script|test" # Квадратные скобки "[]" используются, чтобы провести проверку на соответствие одному из указанных символов: ls | grep "test[23]" test2 test3 # Можем указать "-" для того, чтобы использовать диапазон значений: ls | grep "test[1-3]" test2 test3 # Каретка "^" используется для поиска строк, которые начинаются с указанного шаблона. Давайте найдем совпадение всех строк, начинающихся с заглавной буквы: grep "^[A-Z]" myfile A lot of text Hello world # Знак доллара "$" означает конец строки. В результат входят только те элементы, конец которых подходит под шаблон: grep "world$" myfile Hello world hello world # Точка "." обозначает любой одиночный символ, кроме новой строки. Регулярное выражение "....." обозначает любую строку, содержащую минимум 5 символов: grep '.....' myfile # Вертикальная черта "|" выполняет роль логического оператора "ИЛИ": ls | grep "script\|test" script test # В общем, регулярные выражения прекрасны и многообразны. Детальнее ознакомиться с ними можете по ссылке. # Экранирование # Иногда выражения приводят к неожиданным результатам. # Предположим, вы хотите найти в файле "myfile" только те строки, которые заканчиваются на ".sh". # Следующая команда выдаст неверный результат, поскольку точка — это регулярное выражение, означающее «любой символ»: grep ".sh" myfile script_name.sh script_namesh # Чтобы обойти эту проблему, требуется экранировать спецсимвол: grep "\.sh" myfile script_name.sh # Такое решение иногда становится громоздким. К счастью, можно заставить grep забыть о регулярных выражениях и искать буквально то, что мы указываем. # Для этого используется параметр (fixed) "-F": grep -F ".sh" myfile script_name.sh ``` **Полезные опции для поиска файлов через grep** Иногда нужно найти один/несколько файлов, содержащих определённую строку в: логах, конфигах или исходном коде. Для этого очень часто под рукой оказывается утилита **grep**. Для сводки, интересные флаги и регулярные выражения для grep мы рассматривали тута. По умолчанию команда фильтрует один файл. Для того чтобы выполнять поиск по каталогу, нужно добавить флаг "**-r**": ```sh grep -r "root" /etc/ /etc/mdadm/mdadm.conf:MAILADDR root ``` Если хотим подсветить вхождения цветом, используем опцию "**--color=always**": ```sh grep --color=always -r "root" /etc/ ``` Опции "-**C, -B, -A**" вообще имбовые, использую их целую неделю) Вы можете включить отображение не только текущей строки, в которой было найдено вхождение, но и **n** строк **до/после**: 1) **-C**: выводит n строк до и после вхождения; ```sh grep -C2 -r --color=always "Hello3" ./ ./hello-Hello1 ./hello-Hello2 ./hello:Hello3 ./hello-Hello4 ./hello-Hello5 ``` 1) **-B**: выводит n строк перед вхождением; ```sh grep -B2 -r --color=always "Hello3" ./ ./hello-Hello1 ./hello-Hello2 ./hello:Hello3 ``` 1) **-A**: выводит n строк после вхождения; ```sh grep -A2 -r --color=always "Hello3" ./ ./hello:Hello3 ./hello-Hello4 ./hello-Hello5 ``` Если наш шаблон поиска походит на регулярное выражения, нужно использовать флаг "**-F**". Таким образом мы говорим команде искать ровно то, что мы запросили - без скрытых подтекстов. Без флага мы получим строки, в которых присутствует хотя бы 1 символ из набора (**H, e, l, o**). С флагом получим строки с буквальным совпадением: ```sh grep "[Hello]" hello Help me please Helloup [Hello] ``` ```sh grep -F "[Hello]" hello [Hello] ``` ==================================================== Команды `grep`, `egrep`и `fgrep`являются мощными утилитами для текстового поиска в Linux. Они позволяют пользователям выполнять поиск в файлах или выводе по шаблонам текста с использованием регулярных выражений (regex). В статье мы углубимся в эти команды, их расширенное использование и то, чем они отличаются. **grep** расшифровывается как **Global Regular Expression Print** . Утилита ищет шаблоны в файлах или входных данных и печатает строки, соответствующие шаблону. ### Начнем с простого: базовый синтаксис и флаги grep: `grep [OPTIONS] PATTERN [FILE...] ### Популярные опции: - `-i`: Поиск без учета регистра. - `-v`: Обратное соответствие (показать строки, не соответствующие шаблону). - `-r`: Рекурсивный поиск файлов в каталогах. - `-l`: Показывать только те имена файлов, которые содержат совпадения. - `-c`: Показать количество совпадающих строк. - `-n`: Показывать номера строк с соответствующими строками. - `--color`: Выделение соответствующих шаблонов в выходных данных. - `-f`опция считывает шаблоны из указанного файла - `-F`пропускает механизм регулярных выражений, это быстрее, чем использование обычного`grep` **Примеры:** Поиск без учета регистра: поиск "error" в файле, игнорируя регистр `grep -i "error" /var/log/syslog Рекурсивный поиск в каталоге: поиск шаблона "disk" во всех файлах в /etc/, включая подкаталоги: `grep -r "disk" /etc/ Отображение номеров строк: отображение строк, содержащих "bash" в ~/.bashrc, включая номера строк `grep -n "bash" ~/.bashrc Обратное совпадение: отображение всех строк, не содержащих "root", в /etc/passwd `grep -v "root" /etc/passwd Поиск по нескольким шаблонам с -E: поиск строк, содержащих либо "warn", либо "error" `grep -E "warn|error" /var/log/syslog `egrep`: расширенный `grep`с увеличенной мощностью **egrep** является сокращением от **Extended GREP** . По сути, это то же самое, что и `grep -E`, то есть утилита использует расширенные регулярные выражения, которые поддерживают более продвинутые функции регулярных выражений, такие как `+`, `?`, `|`, и скобки без необходимости их экранирования. Найти строки, содержащие "error" или "fail" без экранирования | `egrep "error|fail" /var/log/syslog Эквивалентно: `grep -E "error|fail" /var/ log /syslog Найти строки с "color" или "colour" `egrep "colou?r" file.txt Расширенные регулярные выражения — шаблоны соответствия: найти строки, где появляется "log", за которым следует 1 или более цифр `egrep "log[0-9]+" logfiles.txt Расширенные шаблоны grep: находим то, что другие не могут найти: 1. Мониторинг системных журналов в режиме реального времени Вы можете использовать `grep` совместно с`tail`для динамического мониторинга журналов и фильтрации определенных шаблонов: `tail -f /var/log/syslog | grep --color=auto -E "error|warn|critical" - **Пояснение:** в примере выше выполняется отслеживание `/var/log/syslog`в реальном времени и фильтрует строки, содержащие «error», «warn» или «critical». Опция `--color`выделяет совпадения. 2. Поиск и замена шаблонов в нескольких файлах Используйте `grep`совместно с `sed`для замены шаблонов в файлах. Это полезно для массовых обновлений в нескольких файлах конфигурации. `grep -rl "old-string" /path/to/directory | xargs sed -i 's/old-string/new-string/g' - **Пояснение**: в примере выше выполняется рекурсивный поиск ( `-r`) всех файлов, содержащих «old-string», и передача их для `sed`замены на «new-string» ( `-i`для редактирования файлов на месте). 3. Извлечение определенных данных из больших логов Для извлечения определенных типов информации, например IP-адресов или временных меток из файла лога, можно использовать расширенные регулярные выражения. **Пример:** извлечение всех IP-адресов из файла лога: `grep -oE "([0-9]{1,3}\.){3}[0-9]{1,3}" /var/log/apache2/access.log - **Пояснение**: в примере выше используется `-oE`для сопоставления IP-адресов (формат адреса IPv4, соответствующий регулярному выражению) и их вывода. **Пример:** извлечение всех временных меток из файлов журнала: `grep -oE "\[([0-9]{2}/[A-Za-z]+/[0-9]{4}):([0-9]{2}:[0-9]{2}:[0-9]{2})" /var/log/apache2/access.log - **Пояснение** : в примере выше извлекаются временные метки лога Apache в формате `[dd/Mon/yyyy:hh:mm:ss]`. 4. Аудит прав доступа к файлам Если вам нужно выполнить аудит безопасности, вы можете использовать `grep`для поиска файлов с определенными разрешениями. **Пример:** найти все файлы с разрешением `777` в каталоге и его подкаталогах: `find / -type f -perm 777 2>/dev/null | grep --color=auto "^" - **Пояснение** в примере выше утилита`find`ищет файлы с разрешениями `777`и направляет вывод в `grep`для их дополнительного выделения цветом. 5. Поиск файлов на основе метаданных (размер, время, владелец) `grep`может использоваться в сочетании с `find`для поиска файлов на основе более конкретных метаданных, таких как время изменения файла, размер и владельцы. **Пример:** найти и отобразить файлы размером более 100 МБ со словом «ERROR»: `find /var/log/ - type f -size +100M - exec grep -H "ERROR" {} \; - **Пояснение**: этот метод использует `find`для поиска файлов размером более 100 МБ в `/var/log/`,а `-exec`запускает `grep`для поиска строк, содержащих «ERROR». **Пример:** найти файлы, измененные за последние 7 дней, и выполнить поиск по слову «failure»: `find /etc/ -type f -mtime -7 -exec grep -H "failure" {} \; - **Пояснение**: `find`ищет файлы, измененные за последние 7 дней, и передает их `grep`для поиска «failure». 6. Параллельный grep для повышения производительности При поиске в больших каталогах с большим количеством файлов параллельный запуск `grep` может значительно повысить производительность. **Пример:** параллельный поиск строки «timeout» в большом каталоге: `find /path/to/dir -type f | xargs -P 4 grep "timeout" - **Пояснение**: `xargs -P 4`запускает параллельно 4 процесса `grep`, ускоряя поиск. 7. Поиск множественных сложных шаблонов Вы можете использовать `grep`для поиска несколько сложных шаблонов, используя расширенные регулярные выражения. **Пример:** поиск строк, содержащих «error» с последующим числом или любую строку с «timeout»: `grep -E "error[[:digit:]]+|timeout" /var/log/syslog - **Пояснение**: этот подход позволяет найти строки, в которых после слова «error» следует одна или несколько цифр, или строки, содержащие слово «timeout». **Пример:** найти в логах строки, содержащие либо «failed login», либо «successful login»: `grep -E "(failed|successful) login" /var/log/auth.log - **Пояснение**: здесь используется расширенное регулярное выражение для сопоставления «failed login» или «successful login». 8. Поиск в двоичных файлах и игнорирование непечатаемых символов `grep`может использоваться для поиска строк в двоичных файлах, игнорируя непечатаемые символы. **Пример:** поиск строки «password» во всех двоичных файлах: `grep -a "password" /usr/bin/* - **Пояснение**: опция `-a` обрабатывает двоичные файлы как текстовые файлы, позволяя искать понятные человеку строки внутри двоичных файлов. 9. Фильтрация и подсчет уникальных вхождений Вы можете использовать `grep` совместно с утилитами`sort`и `uniq`для фильтрации и подсчета уникальных шаблонов, таких как IP-адреса, имена пользователей или ошибки. **Пример:** подсчет уникальных IP-адресов, обращающихся к веб-серверу: `grep -oE "([0-9]{1,3}\.){3}[0-9]{1,3}" /var/log/apache2/access.log | sort | uniq -c | sort -nr - **Пояснение**: эта команда извлекает IP-адреса из access-лога, сортирует их, подсчитывает уникальные вхождения, а затем сортирует их по частоте. **Пример:** найти наиболее частые типы ошибок в файле лога: `grep "ERROR" /var/log/syslog | awk '{print $5}' | sort | uniq -c | sort -nr - **Пояснение**: команда выше извлекает типы ошибок (предполагая, что 5-е поле — это тип ошибки), подсчитывает уникальные ошибки и сортирует их по частоте. ### Повышение производительности: ускорьте поиск с помощью оптимизации grep 10. Объедините grep с другими инструментами автоматизации **Пример:** отправка оповещения, если в журналах появляется определенная ошибка Вы можете создать автоматизированную систему оповещений на основе определенных шаблонов в логах, используя `grep`. `grep -i "critical error" /var/log/syslog | mail -s "Critical Error Found" admin@example.com - **Пояснение**: здесь выполняется поиск «critical error» в системном логе и, если она найдена, администратору отправляется электронное письмо с соответствующими строками. 11. Извлечение определенных данных из диапазона строк Используя `grep`в сочетании с `sed`или `awk`, вы можете извлечь определенные данные из диапазона строк. **Пример:** извлечение линий между двумя шаблонами: `sed -n '/START_PATTERN/,/END_PATTERN/p' file.txt | grep "important_string" - **Пояснение** : в примере выше извлекаются строки между `START_PATTERN`и `END_PATTERN`и передаются в`grep`для поиска `important_string`. 12. grep с удаленных серверов с использованием SSH Вы можете удаленно выполнять поиск в журналах или файлах на другом сервере, используя SSH и `grep`. **Пример:** Поиск «error» в удаленных журналах: `ssh user@remote_server 'grep "error" /var/log/syslog' - **Пояснение**: в примере выше выполняется команда `grep` на удаленном сервере через SSH. 13. Найти выполненные команды в истории Bash Чтобы отследить конкретную команду, использовавшуюся пользователями в прошлом, вы можете выполнить поиск в файлах истории bash. **Пример:** поиск всех выполненных команд `mount` в истории всех пользователей: `grep "mount" /home/*/.bash_history - **Пояснение**: команда выше проверяет файлы истории bash всех пользователей на предмет выполнения ими команды `mount`. 14. Расширенное сопоставление с образцом с отрицательным просмотром `grep`не поддерживает просмотр вперед напрямую, но вы можете добиться похожего поведения с помощью креативного регулярного выражения. **Пример:** сопоставьте строки, содержащие «error», но не содержащие «network error»: `grep -E "error" file.txt | grep -v "network error" - **Пояснение** : сначала команда находит все строки, содержащие «error», а затем исключают строки, содержащие «network error». Эти расширенные варианты использования демонстрируют универсальность `grep`, `egrep`, и `fgrep`при применении в сложных случаях. Независимо от того, анализируете ли вы логи, ищете в больших наборах данных или автоматизируете административные задачи, эти мощные инструменты помогут вам эффективно найти именно то, что вам нужно.