Grep у Linux: Як швидко знайти потрібний рядок у файлі

Grep у Linux: Як швидко знайти потрібний рядок у файлі

 

Команда GREP – огляд

Команда grep у Linux — це потужна утиліта для текстового пошуку, яка дозволяє користувачам шукати у файлах або потоках тексту певні шаблони. Це розшифровується як «глобальний друк регулярних виразів» і підтримує пошук за простими текстовими рядками та складнішими регулярними виразами. Ця команда часто поєднується з іншими командами для фільтрації та уточнення виведених даних. За замовчуванням grep повертає всі рядки, які містять шаблон. Тим не менш, він пропонує різні параметри для налаштування пошуку, такі як чутливість до регістру, підрахунок входжень або рекурсивний пошук у каталогах. Це робить його важливим інструментом для системних адміністраторів, розробників і всіх, хто працює з великими наборами даних в Unix-подібному середовищі.

Команда grep в основному використовується для пошуку в тексті або файлі рядків, які містять збіг із зазначеними словами/рядками. За замовчуванням grep відображає відповідні рядки, і його можна використовувати для пошуку рядків тексту, які відповідають одному або декільком регулярним виразам, і він виводить лише відповідні рядки.

Передумови

Команда grep є частиною базових утиліт будь-якого дистрибутива Linux, тому вона встановлена за замовчуванням на AlmaLinux, CentOS, Debian, Linux Mint, Ubuntu, RHEL і RockyLinux.

Базовий синтаксис команди grep

Базовий синтаксис команди grep виглядає наступним чином:

grep 'word' filename
grep 'word' file1 file2 file3
grep 'string1 string2'  filename
cat otherfile | grep 'something'
command | grep 'something'
command option1 | grep 'data'
grep --color 'data' fileName

Як використовувати команду grep для пошуку у файлі

У першому прикладі я буду шукати користувача “tom” у файлі passwd Linux. Щоб виконати пошук у файлі /etc/passwd користувача “tom”, вам потрібно ввести наступну команду:

grep tom /etc/passwd

Нижче наведено приклад виведення:

tom:x:1000:1000:tom,,,:/home/tom:/bin/bash

У вас є можливість наказати grep ігнорувати регістр слів, тобто відповідати abc, Abc, ABC та всі можливі комбінації з опцією -i, як показано нижче:

grep -i "tom" /etc/passwd

Grep у Linux Як швидко знайти потрібний рядок у файлі

Рекурсивне використання grep

Якщо у вас є купа текстових файлів в ієрархії каталогів, наприклад, файли конфігурації Apache в /etc/apache2/ і ви хочете знайти файл, де визначено конкретний текст, то використовуйте опцію -r команди grep, щоб виконати рекурсивний пошук. Це виконає операцію рекурсивного пошуку файлів для рядка “197.167.2.9” (як показано нижче) у директорії /etc/apache2/ та всіх її підкаталогах:

grep -r "mydomain.com" /etc/apache2/

Крім того, можна використовувати таку команду:

grep -R "mydomain.com" /etc/apache2/

Нижче наведено приклади виводів для аналогічного пошуку на сервері Nginx:

grep -r "mydomain.com" /etc/nginx/
/etc/nginx/sites-available/mydomain.com.vhost:        if ($http_host != "www.mydomain.com") {

Тут ви побачите результат для mydomain.com на окремому рядку, перед яким стоїть назва файлу (наприклад, /etc/nginx/sites-available/mydomain.com.vhost), в якому він був знайдений. Включення імен файлів до вихідних даних можна легко придушити за допомогою параметра -h (як описано нижче): grep -h -R “mydomain.com” /etc/nginx/. Нижче наведено приклад виведення:

grep -r "mydomain.com" /etc/nginx/
if ($http_host != "www.mydomain.com") {

Використання grep для пошуку лише слів

Коли ви шукаєте abc, grep відповідатиме всіляким речам, а саме, kbcabc, abc123, aarfbc35 та багатьом іншим комбінаціям, не підкоряючись обмеженням слів. Ви можете змусити команду grep вибирати лише ті рядки, які містять збіги, щоб утворити цілі слова (ті, які відповідають лише слову abc), як показано нижче:

grep -w "abc" file.txt

Приклад:

Grep у Linux Як швидко знайти потрібний рядок у файлі

Використання grep для пошуку двох різних слів

Щоб знайти два різні слова, ви повинні використовувати команду egrep, як показано нижче:

egrep -w 'word1|word2' /path/to/file

Підрахунок рядків для збігів слів

Команда grep має можливість повідомляти про кількість збігів певного шаблону для кожного файлу за допомогою опції -c (count) (як показано нижче):

grep -c 'word' /path/to/file

Крім того, користувачі можуть використовувати параметр ‘-n’, який передує кожному вихідному рядку з номером рядка у текстовому файлі, з якого його було отримано (як показано нижче):

grep -n 'root' /etc/passwd

Нижче наведено приклади вихідних даних:

1:root:x:0:0:root:/root:/bin/bash

Матч інвертування Grep

Користувачі можуть використовувати опцію -v для друку інверсій збігу, що означає, що він відповідатиме лише тим рядкам, які не містять вказаного слова. Наприклад, надрукуйте всі рядки, які не містять слова par, використовуючи наступну команду:

grep -v par /path/to/file

Як перелічити лише назви відповідних файлів

Ви повинні використовувати параметр -l, щоб вивести список назв файлів, у вмісті яких згадується певне слово, наприклад, слово ‘primary’, за допомогою наступної команди:

grep -l 'primary' *.c

Нарешті, у вас є можливість змусити grep відображати вихідні дані в певних кольорах за допомогою наступної команди:

grep --color root /etc/passwd

Нижче наведено приклади виходів:

Grep у Linux Як швидко знайти потрібний рядок у файлі

Як змусити команду grep обробляти кілька шаблонів пошуку

Можуть виникнути ситуації, коли вам може знадобитися виконати пошук за кількома шаблонами у вказаному файлі (або наборі файлів). У таких сценаріях вам слід використовувати опцію командного рядка ‘-e’, яку надає grep.

Наприклад, припустимо, ви хочете шукати слова “як”, “щоб” і “forge” у всіх текстових файлах, присутніх у вашому поточному робочому каталозі, тоді ось як ви можете це зробити:

grep -e how -e to -e forge *.txt

Ось команда в дії:

Grep у Linux Як швидко знайти потрібний рядок у файлі

Опція командного рядка ‘-e’ також допомагає в сценаріях, коли шаблон починається з дефіса (-). Наприклад, якщо ви хочете шукати, скажімо, “-how”, то наступна команда не буде корисною:

grep -how *.txt

Це коли ви використовуєте опцію командного рядка -e, команда розуміє, що саме ви намагаєтеся шукати в цьому випадку:

grep -e -how *.txt

Ось обидві команди в дії:

Grep у Linux Як швидко знайти потрібний рядок у файлі

Як обмежити вивід grep певною кількістю рядків

Якщо ви хочете обмежити вивід grep певною кількістю рядків, ви можете зробити це за допомогою опції командного рядка ‘-m’. Наприклад, вам потрібно знайти слово “як” у testfile1.txt, яке містить такі рядки:

Grep у Linux Як швидко знайти потрібний рядок у файлі

Але вимога полягає в тому, щоб grep припинив пошук після того, як було знайдено 3 рядки, що містять шуканий шаблон. Отже, для цього можна виконати наступну команду:

grep "how" -m3 testfile1.txt

Ось команда в дії:

Grep у Linux Як швидко знайти потрібний рядок у файлі

Рухаючись далі, ось що сказано на man-сторінці команди:

If the input is standard input from a regular file, and NUM matching lines are output, grep ensuresthat the standard input is positioned to just after the last matching line before exiting, regardless of the presence of trailing context lines. This enables a calling process to resume a search.

Так, наприклад, якщо у вас є скрипт bash, який має цикл, і ви хочете отримати один матч за кожну ітерацію циклу, то використання ‘grep -m1’ зробить необхідне.

Як зробити так, щоб grep отримував шаблони з файлу

Якщо ви хочете, ви також можете зробити так, щоб команда grep отримувала шаблони з файлу. Параметр командного рядка -f цього інструменту дозволяє вам це зробити.

Наприклад, припустимо, що ви хочете шукати у всіх .txt файлах у поточному каталозі слова “як” і “до”, але хочете надати ці вхідні рядки через файл з назвою, скажімо, “input”, тоді ось як ви можете це зробити:

grep -f input *.txt

Ось команда в дії:

Grep у Linux Як швидко знайти потрібний рядок у файлі

Як зробити так, щоб grep відображав тільки ті рядки, які повністю відповідають шаблону пошуку

До цього часу ми бачили, що за замовчуванням grep відповідає та відображає повні рядки, які містять шаблони пошуку. Але якщо вимога полягає в тому, щоб grep відображав лише ті рядки, які повністю відповідають шуканому шаблону, то це можна зробити за допомогою опції командного рядка ‘-x’.

Наприклад, припустимо, testfile1.txt файл містить такі рядки:

Grep у Linux Як швидко знайти потрібний рядок у файлі

І шаблон, який ви хочете пошукати, це «how are you?». Отже, щоб переконатися, що grep відображає лише ті лінії, які повністю відповідають цьому шаблону, використовуйте його наступним чином:

grep -x "how are you?" *.txt

Ось команда в дії:

Grep у Linux Як швидко знайти потрібний рядок у файлі

Як змусити grep нічого не відображати у видачі

Можуть виникнути ситуації, коли вам не потрібна команда grep для створення чогось у виводі. Замість цього, ви просто хочете знати, чи було знайдено збіг на основі стану виходу команди. Цього можна досягти за допомогою параметра командного рядка -q.

У той час як параметр -q вимикає звук виведення, стан виходу інструменту може бути підтверджений командою ‘echo $?’. У випадку з grep, команда завершує роботу зі статусом ‘0’, коли вона успішна (це означає, що збіг був знайдений), тоді як вона завершує роботу зі статусом ‘1’, коли збіг не було знайдено.

На наступному скріншоті показані як вдалі, так і невдалі сценарії:

Grep у Linux Як швидко знайти потрібний рядок у файлі

Як зробити grep відображуваним іменем файлів, які не містять шаблону пошуку

За замовчуванням команда grep відображає назви файлів, що містять шаблон пошуку (а також відповідні рядки). Це цілком логічно, адже саме цього і очікували від цього інструменту. Втім, можуть бути випадки, коли вимогою може бути отримання назв тих файлів, які не містять шуканого шаблону.

Це також можливо за допомогою grep – параметри -L дозволяють це зробити. Так, наприклад, щоб знайти всі ті текстові файли в поточному каталозі, в якому немає слова «як», можна виконати наступну команду:

grep -L "how" *.txt

Ось команда в дії:

Grep у Linux Як швидко знайти потрібний рядок у файлі

Як придушити повідомлення про помилки, що видаються grep

Ви можете змусити grep вимкнути будь-які повідомлення про помилки, які він відображає у виводі, якщо хочете. Це можна зробити за допомогою параметра командного рядка -s. Наприклад, розглянемо наступний сценарій, в якому grep видає помилку/попередження, пов’язане з каталогом, з яким він стикається:

Grep у Linux Як швидко знайти потрібний рядок у файлі

Отже, у таких сценаріях допомагає опція командного рядка -s. Див.

Grep у Linux Як швидко знайти потрібний рядок у файлі

Таким чином, ви можете побачити, що звук помилки/попередження було вимкнено.

Як зробити grep рекурсивно шукати в каталогах

Як зрозуміло з прикладу, використаного в попередньому пункті, команда grep за замовчуванням не виконує рекурсивний пошук. Щоб переконатися, що ваш пошук grep є рекурсивним, використовуйте опцію командного рядка -d і передайте йому значення ‘recurse’.

grep -d recurse "how" *

Примітка 1: Повідомлення про помилку/попередження, пов’язане з каталогом, яке ми обговорювали в попередньому пункті, також можна вимкнути звук за допомогою опції —d — все, що вам потрібно зробити, це передати йому значення «skip».

Примітка 2: Використовуйте опцію ‘–exclude-dir=[DIR]’, щоб виключити каталоги, що відповідають DIR шаблону, з рекурсивних пошуків.

Як змусити grep переривати імена файлів із символом NULL

Як ми вже обговорювали, опція командного рядка -l grep використовується, коли ви хочете, щоб інструмент відображав лише імена файлів у виводі. Наприклад:

Grep у Linux Як швидко знайти потрібний рядок у файлі

Тепер ви повинні знати, що кожне ім’я у наведеному вище виводі відокремлюється/завершується символом нового рядка. Ось як це можна перевірити:

Перенаправте вихідні дані на файл, а потім надрукуйте вміст файлу:

Grep у Linux Як швидко знайти потрібний рядок у файлі

Так, висновок команди cat підтверджує наявність символу нового рядка між іменами файлів.

Але, як ви, можливо, вже знаєте, символ нового рядка також може бути частиною імені файлу. Отже, при роботі з випадками, коли імена файлів містять новий рядок і відокремлюються/завершуються новим рядком, стає важко працювати над виводом grep (особливо при доступі до виводу через скрипт).

Було б добре, якби символ, що розділяє/завершує, не був новим рядком. Що ж, вам буде приємно дізнатися, що grep надає опцію командного рядка -Z, яка гарантує, що за іменами файлів слідує символ NULL, а не новий рядок.

Отже, в нашому випадку командою стає:

grep -lZ "how" *.txt

Ось як ми підтвердили наявність NULL-символу:

Grep у Linux Як швидко знайти потрібний рядок у файлі

Нижче наведено пов’язану опцію командного рядка, яку ви повинні знати:

 -z, --null-data
Treat the input as a set of lines, each terminated by a zero byte (the ASCII NUL character) insteadof a newline. Like the -Z or --null option, this option can be used with commands like sort -z to process arbitrary file names.

Як використовувати GREP для пошуку помилок у файлах журналу

Grep – це швейцарський армійський ніж адміністратора Linux, коли справа доходить до налагодження помилок у службах. Більшість служб Linux мають файли журналів, де вони повідомляють про помилки. Ці файли журналу можуть бути величезними, а grep є універсальною та швидкою командою для пошуку, наприклад, IP-адреси підключеної системи, рядка помилки або адреси електронної пошти постраждалого користувача електронної пошти в mail.log.

Приклади:

Шукайте зв’язки, пов’язані з певною адресою електронної пошти. Тут «user@domain.tld» знаходиться у файлі mail.log сервера.

grep user@domain.tld /var/log/mail.log

Результат:

Aug 22 09:45:10 mail dovecot: pop3-login: Login: user=<user@domain.tld>, method=PLAIN, rip=192.168.0.112, lip=78.46.229.46, mpid=17596, TLS, session=<3uoa5ffQovld3Uep>
Aug 22 09:45:10 mail dovecot: pop3(user@domain.tld)<17596><3uoa5ffQovld3Uep>: Disconnected: Logged out top=0/0, retr=1/6647, del=1/1, size=6630
Aug 22 09:45:10 mail dovecot: pop3-login: Login: user=<user@domain.tld>, method=PLAIN, rip=192.168.0.112, lip=78.46.229.46, mpid=17673, TLS, session=<fIIx6PfQkuBd3Uep>
Aug 22 09:45:10 mail dovecot: pop3(user@domain.tld)<17673><fIIx6PfQkuBd3Uep>: Disconnected: Logged out top=0/0, retr=0/0, del=0/0, size=0
Aug 22 09:45:10 mail dovecot: pop3-login: Login: user=<user@domain.tld>, method=PLAIN, rip=192.168.0.112, lip=78.46.229.46, mpid=17868, TLS, session=<bd5L7ffQPsld3Uep>
Aug 22 09:45:10 mail dovecot: pop3(user@domain.tld)<17868><bd5L7ffQPsld3Uep>: Disconnected: Logged out top=0/0, retr=0/0, del=0/0, size=0
Aug 22 09:45:10 mail dovecot: pop3-login: Login: user=<user@domain.tld>, method=PLAIN, rip=192.168.0.112, lip=78.46.229.46, mpid=17964, TLS, session=<sbpn7vfQevpd3Uep>
Aug 22 09:45:10 mail dovecot: pop3(user@domain.tld)<17964><sbpn7vfQevpd3Uep>: Disconnected: Logged out top=0/0, retr=0/0, del=0/0, size=0
Aug 22 09:45:10 mail postfix/smtpd[6932]: NOQUEUE: reject: RCPT from unknown[1.2.3.4]: 504 5.5.2 <1.2.3.4>: Helo command rejected: need fully-qualified hostname; from=<[email protected]> to=<[email protected]> proto=ESMTP helo=<1.2.3.4>

Щоб постійно відстежувати файл журналу з’єднань для цієї електронної адреси, поєднайте команди tail і grep таким чином:

tail -f /var/log/mail.log | grep user@domain.tld

Щоб вийти з функції годинника, натисніть клавіші [strg] + c.

Прокрутка до верху