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
Якщо у вас є купа текстових файлів в ієрархії каталогів, наприклад, файли конфігурації 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 для пошуку двох різних слів
Щоб знайти два різні слова, ви повинні використовувати команду 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 обробляти кілька шаблонів пошуку
Можуть виникнути ситуації, коли вам може знадобитися виконати пошук за кількома шаблонами у вказаному файлі (або наборі файлів). У таких сценаріях вам слід використовувати опцію командного рядка ‘-e’, яку надає grep.
Наприклад, припустимо, ви хочете шукати слова “як”, “щоб” і “forge” у всіх текстових файлах, присутніх у вашому поточному робочому каталозі, тоді ось як ви можете це зробити:
grep -e how -e to -e forge *.txt
Ось команда в дії:
Опція командного рядка ‘-e’ також допомагає в сценаріях, коли шаблон починається з дефіса (-). Наприклад, якщо ви хочете шукати, скажімо, “-how”, то наступна команда не буде корисною:
grep -how *.txt
Це коли ви використовуєте опцію командного рядка -e, команда розуміє, що саме ви намагаєтеся шукати в цьому випадку:
grep -e -how *.txt
Ось обидві команди в дії:
Як обмежити вивід grep певною кількістю рядків
Якщо ви хочете обмежити вивід grep певною кількістю рядків, ви можете зробити це за допомогою опції командного рядка ‘-m’. Наприклад, вам потрібно знайти слово “як” у testfile1.txt, яке містить такі рядки:
Але вимога полягає в тому, щоб grep припинив пошук після того, як було знайдено 3 рядки, що містять шуканий шаблон. Отже, для цього можна виконати наступну команду:
grep "how" -m3 testfile1.txt
Ось команда в дії:
Рухаючись далі, ось що сказано на 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 відображав тільки ті рядки, які повністю відповідають шаблону пошуку
До цього часу ми бачили, що за замовчуванням grep відповідає та відображає повні рядки, які містять шаблони пошуку. Але якщо вимога полягає в тому, щоб grep відображав лише ті рядки, які повністю відповідають шуканому шаблону, то це можна зробити за допомогою опції командного рядка ‘-x’.
Наприклад, припустимо, testfile1.txt файл містить такі рядки:
І шаблон, який ви хочете пошукати, це «how are you?». Отже, щоб переконатися, що grep відображає лише ті лінії, які повністю відповідають цьому шаблону, використовуйте його наступним чином:
grep -x "how are you?" *.txt
Ось команда в дії:
Як змусити grep нічого не відображати у видачі
Можуть виникнути ситуації, коли вам не потрібна команда grep для створення чогось у виводі. Замість цього, ви просто хочете знати, чи було знайдено збіг на основі стану виходу команди. Цього можна досягти за допомогою параметра командного рядка -q.
У той час як параметр -q вимикає звук виведення, стан виходу інструменту може бути підтверджений командою ‘echo $?’. У випадку з grep, команда завершує роботу зі статусом ‘0’, коли вона успішна (це означає, що збіг був знайдений), тоді як вона завершує роботу зі статусом ‘1’, коли збіг не було знайдено.
На наступному скріншоті показані як вдалі, так і невдалі сценарії:
Як зробити grep відображуваним іменем файлів, які не містять шаблону пошуку
За замовчуванням команда grep відображає назви файлів, що містять шаблон пошуку (а також відповідні рядки). Це цілком логічно, адже саме цього і очікували від цього інструменту. Втім, можуть бути випадки, коли вимогою може бути отримання назв тих файлів, які не містять шуканого шаблону.
Це також можливо за допомогою grep – параметри -L дозволяють це зробити. Так, наприклад, щоб знайти всі ті текстові файли в поточному каталозі, в якому немає слова «як», можна виконати наступну команду:
grep -L "how" *.txt
Ось команда в дії:
Як придушити повідомлення про помилки, що видаються grep
Ви можете змусити grep вимкнути будь-які повідомлення про помилки, які він відображає у виводі, якщо хочете. Це можна зробити за допомогою параметра командного рядка -s. Наприклад, розглянемо наступний сценарій, в якому grep видає помилку/попередження, пов’язане з каталогом, з яким він стикається:
Отже, у таких сценаріях допомагає опція командного рядка -s. Див.
Таким чином, ви можете побачити, що звук помилки/попередження було вимкнено.
Як зробити grep рекурсивно шукати в каталогах
Як зрозуміло з прикладу, використаного в попередньому пункті, команда grep за замовчуванням не виконує рекурсивний пошук. Щоб переконатися, що ваш пошук grep є рекурсивним, використовуйте опцію командного рядка -d і передайте йому значення ‘recurse’.
grep -d recurse "how" *
Примітка 1: Повідомлення про помилку/попередження, пов’язане з каталогом, яке ми обговорювали в попередньому пункті, також можна вимкнути звук за допомогою опції —d — все, що вам потрібно зробити, це передати йому значення «skip».
Примітка 2: Використовуйте опцію ‘–exclude-dir=[DIR]’, щоб виключити каталоги, що відповідають DIR шаблону, з рекурсивних пошуків.
Як змусити grep переривати імена файлів із символом NULL
Як ми вже обговорювали, опція командного рядка -l grep використовується, коли ви хочете, щоб інструмент відображав лише імена файлів у виводі. Наприклад:
Тепер ви повинні знати, що кожне ім’я у наведеному вище виводі відокремлюється/завершується символом нового рядка. Ось як це можна перевірити:
Перенаправте вихідні дані на файл, а потім надрукуйте вміст файлу:
Так, висновок команди cat підтверджує наявність символу нового рядка між іменами файлів.
Але, як ви, можливо, вже знаєте, символ нового рядка також може бути частиною імені файлу. Отже, при роботі з випадками, коли імена файлів містять новий рядок і відокремлюються/завершуються новим рядком, стає важко працювати над виводом grep (особливо при доступі до виводу через скрипт).
Було б добре, якби символ, що розділяє/завершує, не був новим рядком. Що ж, вам буде приємно дізнатися, що grep надає опцію командного рядка -Z, яка гарантує, що за іменами файлів слідує символ NULL, а не новий рядок.
Отже, в нашому випадку командою стає:
grep -lZ "how" *.txt
Ось як ми підтвердили наявність NULL-символу:
Нижче наведено пов’язану опцію командного рядка, яку ви повинні знати:
-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.