Grep как найти каталог

Универсальная команда grep позволяет выполнять поиск текста во всех файлах и всех подкаталогах каталога.

Grep – это отличный инструмент, когда вам нужно выполнить поиск по содержимому файла.

Обычно вы запускаете grep на одном файле, например, так:

grep search_term filename

Grep достаточно универсален.

Если вы хотите найти все файлы в каталоге с помощью grep, используйте его следующим образом:

grep search_term *

С этим есть проблема.

Он ищет только во всех файлах в текущем каталоге.

Он не будет искать в подкаталогах.

Вы можете заставить grep искать во всех файлах и во всех подкаталогах текущего каталога, используя опцию -r рекурсивного поиска:

grep -r search_term . 

Вы также можете указать путь к каталогу, если вы находитесь не в том каталоге, в котором хотите выполнить поиск:

grep -r search_term directory_path

Это был краткий обзор.

Позвольте мне показать вам все это в деталях с соответствующими примерами, чтобы вам было легче понять.

Поиск Grep во всех файлах каталога

Вот структура каталогов, которую я собираюсь использовать в этом примере.

За исключением файла empty.txt, все файлы содержат термин ‘simple’, по которому я буду выполнять поиск grep.

~/scripts$ tree
.
├── dir1
│   └── new_script.sh
├── dir2
│   └── your_script.sh
├── dir3
│   ├── empty.txt
│   └── linked.txt -> ../../sample.txt
├── my_script.sh
└── your_script.sh

3 directories, 6 files

Для поиска слова ‘simple’ во всех файлах текущей директории достаточно использовать подстановочный знак (*).

grep simple *

Это приведет к поиску во всех файлах в текущих каталогах, но не зайдет в подкаталоги.

Поскольку вы не можете напрямую искать grep в каталоге, система выдаст ошибку “XYZ is a directory”  вместе с результатами поиска.

Если вы находитесь не в том же каталоге, в котором хотите выполнить, вы можете указать путь к каталогу и закончить его символом /*

grep search_term directory_path/*

По сути, вы используете * для расширения всех элементов (файлов и каталогов) данного каталога.

Теперь, когда вы это знаете, давайте посмотрим, как можно выполнить рекурсивный поиск с помощью grep, чтобы он также просматривал файлы в подкаталогах.

Рекурсивный поиск Grep во всех подкаталогах каталога

Grep предоставляет опцию -r для рекурсивного поиска.

С этой опцией grep будет искать все файлы в текущем (или указанном) каталоге, а также все файлы во всех подкаталогах.

Вот рекурсивный поиск, который я выполнил в предыдущем примере:

grep -r simple .

Существует также опция -R для рекурсивного поиска, и она работает почти так же, как опция -r.

grep -R simple .

Итак, в чем разница между grep -r и grep -R?

На самом деле, только одна.

Поиск -R является поиском с разыменованием, что означает, что он будет следовать по символическим ссылкам, чтобы перейти к исходному файлу (который может находиться в какой-то другой части системы).

Если вы находитесь не в том каталоге, в котором хотите выполнить рекурсивный поиск, просто укажите команде grep абсолютный или относительный путь к каталогу:

grep -r search_term path_to_directory

Бонусный совет: Как исключить определенный каталог из рекурсивного поиска grep

Все вроде бы хорошо, но что если вы хотите исключить определенный каталог из рекурсивного поиска?

Для этого тоже есть соответствующая возможность.

Я уже говорил вам, что grep – чрезвычайно универсальная команда.

grep -r --exclude-dir=dir_name serach_term directory_path

Это еще не все.

Вы можете исключить из рекурсивного поиска более одного подкаталога следующим образом:

grep -r --exclude-dir={dir1,dir2} serach_term directory_path

Подведем итоги

Вот краткий обзор использования поиска grep для нескольких файлов и каталогов:

Команда Grep Описание
grep string * Поиск во всех файлах в текущем каталоге
grep string dir Поиск во всех файлах в каталоге dir
grep -r string . Рекурсивный поиск во всех файлах во всех подкаталогах
grep -r string dir Рекурсивный поиск во всех файлах во всех подкаталогах каталога dir
grep -R string . То же, что и r, но следует за символическими ссылками

см. также:

  • 🧾 Как скачать, установить и использовать GNU Grep в Windows?
  • ngrep – Сетевой анализатор пакетов для Linux

Перевод публикуется с сокращениями, автор оригинальной статьи 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
Команда GREP - «швейцарский нож» в арсенале администратора Linux-сервера

В статье про поиск файлов и папок мы говорили про команду find и том, как ее использовать на сервере для оптимального поиска чего-либо. Но в арсенале системного администратора Linux-сервера также имеется команда под названием grep, про которую сегодня хочу рассказать читателям и подписчикам. Давайте познакомимся с ней, поймем в чем разница между find и grep и когда лучше использовать каждую команду.

Поиск файлов и папок через терминал в Linux-дистрибутивах

Не забываем также подписаться на обновления канал Просто Код в телеграме. Так вы будете получать уведомления о новых постах быстрее, чем уведомляет об этом Дзен.

Что делает команда GREP?

GREP расшифровывается как Global Regular Expression Print, что говорит о том, что она используется для поиска строк и шаблонов в группе файлов или папок, а также среди данных, которыми оперируют другие команды и процессы на сервере. Как это часто бывает в Linux, это не просто название команды, а отдельная системная и консольная утилита. В основе работы утилиты лежит расширенный синтаксис регулярных выражений, который появился в UNIX-системах 1981 году. GREP встречается во всех дистрибутивах Linux.

Синтаксис команды

Познакомимся с синтаксисом (то есть, правилами написания) команды grep.

grep [опции] [регулярное выражение] [место поиска – файл или директория]

Но чаще всего grep используется в качестве команды, которой передают «выхлоп» (то есть, результат работы) другой команды для фильтрации и конечного вывода в терминал.

Фильтруем «выхлоп» других команд

Вспомним про команду ls, которая выводит списком содержимое директории. В тестовом примере ниже у меня есть папка Test, внутри которой есть как файлы, так и папки. Файлы имеют имя File<набор_символов>, папки названы как Folder<набор_символов>. Мне нужно показать только папки и единственное, что я помню – это то, что каждая папка имеет имя Folder. Воспользуемся командами ls и grep, чтобы реализовать задуманное

ls | grep Folder

Символ прямой черты | еще называют «трубкой», он принимает выходные данные одной команды и передает их следующей в качестве входных данных. То есть, мы передали «выхлоп» команды ls в качестве входных данных команде grep, которая отфильтровала результаты и показала только то, что содержит в имени Folder. В моем примере папок всего четыре, но представьте, если бы их было несколько десятков и сотен – тогда бы подобная фильтрация сильно сэкономила время.

Команда GREP - «швейцарский нож» в арсенале администратора Linux-сервера

В следующем примере нам нужны и файлы, и папки, которые имеют в имени какую-либо постоянную часть. Это может быть имя сервера, дата бэкапа и пр.

ls | grep ABC

Команда GREP - «швейцарский нож» в арсенале администратора Linux-сервера

Ну, и наконец, более практичный пример. Очень часто на сервере нужно посмотреть какой порт «прослушивается» каким-либо процессом или программой. Для этого тоже можно использовать команду grep, чтобы отфильтровать значения до нужных. В команде ниже я вывожу порты, которые слушает протокол ssh.

sudo netstat -lntup | grep “ssh”

Команда GREP - «швейцарский нож» в арсенале администратора Linux-сервера

Поиск строк в файлах

Представим ситуацию, что у вас есть папка с сайтом. И внутри множества файлов этого сайта нужно найти конкретное слово. Не вручную же перебирать все файлы! Для этого тоже можно использовать команду grep. Например, среди пяти файлов в папке Test попробуем найти те, где используется слово «grep»:

grep -R “grep” Test

Команда GREP - «швейцарский нож» в арсенале администратора Linux-сервера

Если нам необходимо объединить выражения и осуществить поиск нескольких строк, то нужно использовать ключ -e. Это своего рода указание «или» для утилиты. Попробуем найти среди наших файлов те, где встречаются слова «grep» или «php»:

grep -R -e “grep” -e “php” Test

Команда GREP - «швейцарский нож» в арсенале администратора Linux-сервера

Также вместо папки мы можем указать имя конкретного файла (убрав перед этим ключ -R) и попытаться найти нужные строки в нем.

grep “grep” <имя_файла>

Если в файле не будет ничего найдено, то команда вернет пустую строку.

Команда GREP - «швейцарский нож» в арсенале администратора Linux-сервера

Для расширения возможностей поиска строк в файлах можно использовать следующие ключи и так называемые якоря:

  • grep -i – поиск без учета регистра
  • grep -w – поиск по всему слову
  • grep -v – обратный поиск (то есть, он вернет все, что не соответствует заданной после строке)
  • grep -r -L – вернет имена файлов, в которых отсутствует заданный после шаблон для поиска
  • grep -n – выведет не просто найденную строку, но и укажет ее номер в документе
  • grep -A<количество> – выводит найденную строку и следующую строку после совпадения, количество выводимых строк можно менять
  • grep -B<количество> – выводит найденную строку и предыдущую строку до совпадения, количество выводимых строк можно менять
  • grep -C<количество> – выводит найденную строку и строки до и после совпадения, количество выводим строк можно менять
  • grep -q – запуск команды в тихом режиме, после выполнения она просто сохранит код статуса в системной переменной $? (если 0, то совпадения есть, если 1, то совпадений нет); такой метод используют в скриптах для проверки условий, когда не нужно выводить конкретную заданную строку.
  • grep “^” – якорь ^ говорит, что совпадение должно быть в начале строки
  • grep “$” – якорь $ говорит, что совпадение должно быть в конце строки
  • grep “<” – якорь < привязывает совпадение к началу слов
  • grep “>” – якорь > привязывает совпадение к концу слов

Поиск при помощи регулярных выражений (regular expression)

По-настоящему функционал grep раскрывается при использовании регулярных выражений. Раскрыть возможности их использования в одной статье невозможно, поэтому думаю, что работе с регулярными выражениями можно посвятить отдельную статью. Давайте договоримся о том, что если такая статья вам интересна, то вы поставите этому посту лайк и как только их наберется 15 штук, я подготовлю материал по regular expression.

Отличия grep и find

Отличия между двумя командами следующие:

  • команду grep лучше использовать для поиска содержимого внутри файлов и папок, тогда как find идеально подойдет если вы желаете найти сам файл или папку (она и найдет, и путь нужный выведет).
  • команда find используется для поиска полных имен файлов и папок в системе, тогда как grep лучше использовать для нечеткого запроса (если уж вы все же решитесь искать файлы и папки с помощью grep)
  • команда find использует для поиск стандартные (системные) шаблоны, тогда как в grep такие шаблоны может задавать пользователь

Итог

Тема использования grep обширна, на самом деле, там есть огромное количество полезных штук, лишь только часть из них я показал в рамках материала. Задача статьи – не рассказать про grep ВСЕ, а познакомить новичков с этой утилитой и мотивировать ее изучать и использовать на практике. Думаю, что в комментариях опытные подписчики и читатели смогут дополнить материал нужной информацией и конкретными примерами использования grep.

Давайте же поддержим канал подпиской, лайком и комментариями, ведь чем больше активности вы проявляете, тем чаще алгоритмы Дзена показывают посты в ленте рекомендаций.

Если не подписались на уведомления канала в Телеграм, то самое время сделать это, ведь информация о новых заметках приходит там сразу в момент публикации!

Команда 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 expressiongrep -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 .

Если у вас есть какие-либо вопросы или отзывы, не стесняйтесь оставлять комментарии.

Get the first matched files from grep command and get all the files don’t contain some word, but input files for second grep comes from result files of first grep command.

grep -l -r --include "*.js" "FIRSTWORD" * | xargs grep "SECONDwORD"
grep -l -r --include "*.js" "FIRSTWORD" * | xargs grep -L "SECONDwORD"

dc0fd654-37df-4420-8ba5-6046a9dbe406

grep -l -r --include "*.js" "SEARCHWORD" * | awk -F'/' '{print $NF}' | xargs -I{} sh -c 'echo {}; grep -l -r --include "*.html" -w --include=*.js -e {} *;  echo '''

5319778a-cec2-444d-bcc4-53d33821fedb

grep "SEARCH_STRING" *.log | grep -e "http" -e "https" | awk '{print $NF}' | uniq

ce91d131-a5c2-4cc8-b836-1461feee6cdb

Here’s how you can modify the command to extract the value of messageName:

grep -m 2 "In sendMessage:: " *LOGFILE.log | grep -o -e "messageName=[^,]*" | cut -d= -f2 | sort | uniq | tee >(echo "Number of unique values: $(wc -l)")

grep "In Message:: " *messaging.log | grep -o -e "messageName=[^,]*" | cut -d= -f2 | sort | uniq | while read -r messageName; do grep -m 1 "In  sendMessage:: .*messageName=${messageName}" *logfile.log | head -n 1; done

I want to use run below grep command over above files
2. files to be sorted in descending order based on their update time and not matching the .gz format

grep "org.springframework.batch.item.ItemStreamException: Failed to initialize the reader at" $(ls -lrth | grep -i opti | awk '{print $NF}')
      grep -A 15 "request to URL : SEARCH" $(ls -lth | grep "common" | grep -v ".gz"  | awk '{print $NF}')

command to create a new file from the first occurrence to the last occurrence.

sed -n '/14 Jan 2023/,/14 Jan 2023/p' common.log > common_1day.log

Today modified files,

ls -lrth $(find . -type f -name "*.log" -newermt "$(date -R -d 'today 00:00')" -print)
grep "CID" $(find . -type f -name "*.log" -newermt "$(date -R -d 'today 00:00')" -print)
zgrep "SEARCH" $(find . -type f -newermt "$(date -R -d 'today 00:00')" -print)
ls -lrth $(find . -type f -name "*" -newermt "$(date -R -d 'today 00:00')" -print)
less +G $(find . -type f -name "*LOG_FILE.log" -newermt "$(date -R -d 'today 00:00')" -print)
grep Async $(find . -type f -name "*" -newermt "2023-04-14 00:00:00" ! -newermt "2023-04-16 00:00:00" -print)

Find commands

find . -type f -not -path "*/target/*" -name "log4j2.xml" -exec grep -H '<Async name="' {} ;

Добавить комментарий