Команда grep в Linux — це утиліта зіставлення рядків і шаблонів, яка відображає відповідні рядки з кількох файлів. Він також працює з конвейерним виводом інших команд. Ми покажемо вам, як.
Історія grep
Команда grep відома в Linux і Unix кола з трьох причин. По-перше, це надзвичайно корисно. По-друге, багатство варіантів може бути вражаючим. По-третє, вона була написана за одну ніч, щоб задовольнити певну потребу. Перші два – трішки; третій злегка згорнутий.
Кен Томпсон витягнув можливості пошуку регулярних виразів із редактора ed (вимовляється ee-dee) і створив невелику програму — для власного використання — для пошуку в текстових файлах. Його начальник відділу в Bell Labs, Дуг Макілрой, підійшов до Томпсона і описав проблему одному зі своїх колег, Лі Макмехон, стикався.
Макмехон намагався ідентифікувати авторів Федералістські документи через текстовий аналіз. Йому потрібен був інструмент, який міг би шукати фрази та рядки в текстових файлах. Того вечора Томпсон витратив близько години, зробивши свій інструмент загальною утилітою, якою могли б користуватися інші, і перейменував його на grep. Він взяв назву з командного рядка ed g/re/p, що перекладається як «глобальний пошук регулярних виразів».
Ви можете спостерігати, як Томпсон говорить до Браян Керніган про народження греп.
Простий пошук за допомогою grep
Щоб шукати рядок у файлі, передайте пошуковий термін та ім’я файлу в командному рядку:
Відображаються відповідні рядки. В даному випадку це один рядок. Відповідний текст виділено. Це тому, що в більшості дистрибутивів grep має псевдонім:
alias grep='grep --colour=auto'
Давайте подивимося на результати, де є кілька рядків, які збігаються. Ми шукаємо слово «Середнє» у файлі журналу програми. Оскільки ми не можемо згадати, чи є слово в нижньому регістрі у файлі журналу, ми будемо використовувати параметр -i (ігнорувати регістр):
grep -i Average geek-1.log
Відображається кожен відповідний рядок, у кожному з яких виділено відповідний текст.
Ми можемо відобразити невідповідні рядки за допомогою параметра -v (інвертувати відповідність).
grep -v Mem geek-1.log
Немає виділення, тому що це лінії, що не збігаються.
Ми можемо змусити grep бути повністю безшумним. Результат передається в оболонку як значення, що повертається з grep. Результат нуля означає, що рядок знайдено, а результат одиниці означає, що його не знайдено. Ми можемо перевірити код повернення за допомогою $? спеціальні параметри:
grep -q average geek-1.log
echo $?
grep -q wdzwdz geek-1.log
echo $?
Рекурсивний пошук за допомогою grep
Для пошуку у вкладених каталогах і підкаталогах використовуйте параметр -r (рекурсивний). Зауважте, що ви не вказуєте ім’я файлу в командному рядку, ви повинні вказати шлях. Тут ми шукаємо в поточному каталозі “.” і будь-які підкаталоги:
grep -r -i memfree .
Вихідні дані включають каталог та ім’я файлу кожного відповідного рядка.
Ми можемо змусити grep слідувати символічним посиланням, використовуючи параметр -R (рекурсивне розіменування). Ми маємо символічне посилання в цьому каталозі, яке називається logs-folder. Він вказує на /home/dave/logs.
ls -l logs-folder
Давайте повторимо наш останній пошук за допомогою параметра -R (рекурсивне розіменування):
grep -R -i memfree .
Перехід за символічним посиланням і каталог, на який воно вказує, також шукається за допомогою grep.
Пошук цілих слів
За замовчуванням, grep буде відповідати рядку, якщо пошукова мета з’являється де-небудь у цьому рядку, в тому числі всередині іншого рядка. Подивіться на цей приклад. Ми будемо шукати слово «безкоштовно».
grep -i free geek-1.log
Результатом є рядки, у яких є рядок «free», але це не окремі слова. Вони є частиною рядка «MemFree».
Щоб змусити grep відповідати лише окремим «словам», використовуйте параметр -w (регулярний вираз слова).
grep -w -i free geek-1.log
echo $?
Цього разу немає результатів, оскільки пошуковий термін «безкоштовно» не відображається у файлі як окреме слово.
Використання кількох пошукових термінів
Параметр -E (розширений регулярний вираз) дозволяє шукати кілька слів. (Параметр -E замінює застарілі egrep версія grep.)
Ця команда шукає два терміни пошуку: «середній» і «без пам’яті».
grep -E -w -i "average|memfree" geek-1.log
Усі відповідні рядки відображаються для кожного з пошукових термінів.
Ви також можете шукати кілька термінів, які не обов’язково є цілими словами, але вони також можуть бути цілими словами.
Параметр -e (шаблони) дозволяє використовувати декілька пошукових термінів у командному рядку. Ми використовуємо функцію дужки регулярного виразу, щоб створити шаблон пошуку. Він вказує grep відповідати будь-якому із символів, що містяться в дужках «[]». Це означає, що grep під час пошуку відповідатиме «kB» або «KB».
Обидва рядки збігаються, і, насправді, деякі рядки містять обидва рядки.
Точно відповідні лінії
-x (рядковий регулярний вираз) буде відповідати лише рядкам, де весь рядок відповідає пошуковому терміну. Давайте шукаємо мітку дати та часу, яка, як ми знаємо, з’являється лише один раз у файлі журналу:
grep -x "20-Jan--06 15:24:35" geek-1.log
Один рядок, який відповідає, знайдено та відображено.
Протилежність цьому показує лише рядки, які не збігаються. Це може бути корисно, коли ви переглядаєте файли конфігурації. Коментарі чудові, але іноді важко помітити фактичні налаштування серед них. Ось файл /etc/sudoers:
Ми можемо ефективно відфільтрувати рядки коментарів, як це:
sudo grep -v "https://www.wdzwdz.com/496056/how-to-use-the-grep-command-on-linux/#" /etc/sudoers
Це набагато легше розібрати.
Відображення лише відповідного тексту
Можливо, ви захочете бачити не весь відповідний рядок, а лише відповідний текст. Параметр -o (тільки відповідний) робить саме це.
grep -o MemFree geek-1.log
Відображення зменшується до показу лише тексту, який відповідає пошуковому терміну, замість усього відповідного рядка.
Підрахунок за допомогою grep
grep — це не лише текст, він також може надавати числову інформацію. Ми можемо підрахувати grep різними способами. Якщо ми хочемо знати, скільки разів пошуковий термін з’являється у файлі, ми можемо використовувати параметр -c (лічильник).
grep -c average geek-1.log
grep повідомляє, що пошуковий термін з’являється в цьому файлі 240 разів.
Ви можете змусити grep відображати номер рядка для кожного відповідного рядка за допомогою параметра -n (номер рядка).
grep -n Jan geek-1.log
Номер рядка для кожного відповідного рядка відображається на початку рядка.
Щоб зменшити кількість результатів, які відображаються, використовуйте параметр -m (максимальна кількість). Ми збираємося обмежити вихід до п’яти відповідних рядків:
grep -m5 -n Jan geek-1.log
Додавання контексту
Можливість побачити деякі додаткові рядки (можливо, невідповідні рядки) для кожного відповідного рядка часто корисно. це може допомогти визначити, які з відповідних рядків є тими, які вас цікавлять.
Щоб показати деякі рядки після відповідного рядка, використовуйте параметр -A (після контексту). У цьому прикладі ми просимо три рядки:
grep -A 3 -x "20-Jan-06 15:24:35" geek-1.log
Щоб побачити рядки перед відповідним рядком, використовуйте параметр -B (контекст перед).
grep -B 3 -x "20-Jan-06 15:24:35" geek-1.log
А щоб включити рядки до і після відповідного рядка, використовуйте параметр -C (контекст).
grep -C 3 -x "20-Jan-06 15:24:35" geek-1.log
Відображення відповідних файлів
Щоб побачити назви файлів, які містять пошуковий термін, використовуйте параметр -l (файли зі збігом). Щоб дізнатися, які файли вихідного коду C містять посилання на файл заголовка sl.h, скористайтеся цією командою:
grep -l "sl.h" *.c
Перераховані імена файлів, а не відповідні рядки.
І, звичайно, ми можемо шукати файли, які не містять пошукового терміну. Параметр -L (файли без відповідності) робить саме це.
grep -L "sl.h" *.c
Початок і кінець рядків
Ми можемо змусити grep відображати лише збіги, які знаходяться або на початку, або в кінці рядка. Оператор регулярного виразу «^» відповідає початку рядка. Практично всі рядки у файлі журналу будуть містити пробіли, але ми збираємося шукати рядки, які мають пробіл як перший символ:
grep "^ " geek-1.log
Відображаються рядки, які мають пробіл як перший символ — на початку рядка.
Щоб узгодити кінець рядка, використовуйте оператор регулярного виразу «$». Ми будемо шукати рядки, які закінчуються на «00».
grep "00$" geek-1.log
На дисплеї відображаються рядки, кінцевими символами яких є «00».
Використання Pipes з grep
Звичайно, ви можете передати вхід до grep , передати вихід з grep в іншу програму і розмістити grep в середині ланцюжка конвеєрів.
Скажімо, ми хочемо побачити всі входження рядка «ExtractParameters» у наші файли вихідного коду C. Ми знаємо, що їх буде досить багато, тому ми розраховуємо менше:
grep "ExtractParameters" *.c | less
Вихід представлений у меншому розмірі.
Це дозволяє переглядати список файлів і використовувати засоби пошуку less.
Якщо ми переведемо вихід з grep в wc і скористаємося опцією -l (рядки), ми може порахувати кількість рядків у файлах вихідного коду, які містять «ExtractParameters». (Ми могли б досягти цього за допомогою параметра grep -c (count), але це зручний спосіб продемонструвати конвеєрство з grep.)
grep "ExtractParameters" *.c | wc -l
За допомогою наступної команди ми передаємо вихід з ls в grep і передаємо вихід з grep в sort . Ми перераховуємо файли в поточному каталозі, вибираючи ті, у яких є рядок «Aug», і сортування їх за розміром файлу:
ls -l | grep "Aug" | sort +4n
Давайте розберемо це:
ls -l: Виконайте довгий перелік файлів у форматі за допомогою ls.
grep «Aug»: виберіть рядки зі списку ls, у яких є «Aug». Зауважте, що це також знайде файли, у іменах яких є «Aug».
sort +4n: сортування виводу з grep у четвертому стовпці (розмір файлу).
Ми отримуємо відсортований список усіх файлів, змінених у серпні (незалежно від року), у порядку зростання розміру файлу.
grep: Менше команди, більше союзника
grep — чудовий інструмент, який можна мати у вашому розпорядженні. Він датується 1974 роком і все ще діє, тому що нам потрібно те, що він робить, і ніщо не робить його краще.
Поєднання grep з деякими регулярними виразами-fu дійсно виводить його на наступний рівень.