19 сентября, Москва — конференция Business Day для IT-руководителей

Команда grep в Linux

Миша Курушин
Миша Курушин
Технический писатель
23 августа 2024 г.
268
12 минут чтения
Средний рейтинг статьи: 5

Команда grep встроена во множество дистрибутивов операционной системы Linux. Она запускает утилиту, которая выполняет поиск либо конкретного файла с указанным текстом, либо конкретной строки внутри файла с указанными символами.

Название «grep» является акронимом «global regular expression print». Некоторые разработчики говорят просто «грепать» — то есть искать какое-либо регулярное выражение в большом объеме файлов.

На вход команде можно подавать не только директории с файлами для поиска, но и текстовый вывод других команд, тем самым фильтруя его.

В этой статье мы подробно рассмотрим использование команды grep:

  • разберемся с синтаксисом команды;
  • протестируем работу регулярных выражений;
  • попробуем различные опции во время работы команды;
  • выполним поиск как в отдельном файле, так и в целом каталоге;
  • поймем, как включать и исключать отдельные файлы из поиска;

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

Схематически команда выглядит так:

grep [флаги] выражение [<путь к директории или файлу>]
  • В самом начале указываются различные параметры-флаги, с помощью которых настраивается механизм поиска и вывода.
  • Далее указывается регулярное выражение, которое используется для поиска текста.
  • Самый последний аргумент — путь либо к файлу, либо к директории с файлами. Именно там и будет выполняться поиск. При это если указана папка, то поиск выполняется рекурсивно.

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

другая_команда | grep [флаги] выражение

Это помогает отфильтровывать наиболее важную информацию среди прочей менее важной в момент вывода из других программ.

Что касается регулярных выражений, то они — основа команды grep. Они необходимы для создания шаблонов поиска.

Забегая вперед, у регулярных выражений есть два уровня — базовый (Basic Regular Expressions, BRE) и расширенный (Extended Regular Expressions, ERE). Чтобы включить последний, необходимо использовать флаг -E.

Тонкости использования утилиты grep лучше всего разбирать на реальных примерах — в виде небольших задач. Далее мы последовательно рассмотрим основные варианты поиска строк внутри файлов.

Подготовка системы

В примерах этой инструкции использовалась операционная система Ubuntu 22.04, размещенная в облаке Timeweb Cloud.

Чтобы создать аналогичный облачный сервер, нужно сперва авторизоваться в Timeweb Cloud.

Image2

Страница авторизации Timeweb Cloud

После этого в панели управления нужно перейти на страницу «Облачные серверы» и нажать на кнопку «Создать».

Откроется конфигуратор облачного сервера. Настройка довольна простая — около 8 параметров. Самый основной — операционная система. Нужно выбрать Ubuntu 22.04.

Image3

Страница конфигурации облачного сервера

Далее жмем создать «Заказать» и оказывается на странице управления облачным сервером. Пару минут нужно подождать, пока сервер подготовится и запустится.

После этого можно подключиться к удаленному хосту по SSH через консольный терминал вашей системы на основе тех данных, которые указаны на главной странице управления сервером.

Для этого понадобится IPv4-адрес и Root-пароль.

Image1

Справа на главной странице облачного сервера есть данные для удаленного подключения

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

cloud

Создание текстовых файлов

После настройки операционной системы нужно немного настроить ее окружение. В частности файловую систему, с которой мы будем работать.

Каталог для файлов

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

Создадим отдельную папку под файлы:

mkdir files

После чего перейдем в нее:

cd files

Файл с русским текстом

Здесь мы разместим файл, который будет содержать текст на русском языке:

sudo nano russian1

Содержимым выступит отрывок стихотворения Пушкина:

У лукоморья дуб зелёный
Златая цепь на дубе том
И днём и ночью кот учёный
Всё ходит по цепи кругом

Файл с английским текстом

И еще один файл на английском:

sudo nano english1

Содержимым выступит отрывок из произведения «Гордость и предубеждение», которое написала Джейн Остин:

However little known the feelings or views of such a man may be on his first entering a neighbourhood, this truth is so well fixed in the minds of the surrounding families, that he is considered as the rightful property of some one or other of their daughters.

Файл с кодом

Еще один файл будет содержать простой код на JavaScript:

sudo nano code1

Содержимое такое:

const number1 = 2;
const number2 = 4;

const sum = number1 + number2;

console.log('Сумма чисел ' + number1 + ' и ' + number2 + ' равна ' + sum);

Список созданных файлов

Проверим наличие созданных файлов:

ls

Консоль должна вывести такой список:

code1  english1  russian1

Отлично! Именно на этих файлах мы и протестируем работу команды grep.

Поиск через регулярные выражения

Простое вхождение

Давайте попробуем найти все артикли «the» в файле с английским текстом:

grep 'the' english1

В консоли появится найденные элементы, в которых красным цветом будут помечены все вхождения «the».

Однако есть одна проблема — grep также указал на слова «other» и «their», которые не являются артиклями.

Чтобы найти только артикли, можно использовать специальный флаг -w. Благодаря нему будет выполнять поиск только целых слов, без вхождений указанного набора символов:

grep -w 'the' english1

Теперь консольный терминал выделит красным только те «the», которые не являются частью другого слова.

Конец строки

Можно усложнить регулярное выражение, добавив специальный оператор. Например, мы можем найти только строки, оканчивающиеся определенным набором символов:

grep 'ый$' russian1

Консоль выведет только те строки, в которых есть указанные вхождения, — их она подсветит красным цветом:

У лукоморья дуб зелёный
И днём и ночью кот учёный

Флаги поиска

Поиск по расширенным регулярным выражениям (-E)

Можно активировать расширенные регулярные выражения, указав флаг -E. Расширенный режим добавляет несколько новых символов, делая поиск еще более гибким.

+

символ повторяется один или более раз

?

символ повторяется ноль или более раз

{n, m}

символ повторяется от n до m раз 

|

разделитель, объединяющий разные паттерны

Небольшой пример использования расширенных регулярных выражений:

grep -E '[а-я]+ом$' ./*

Здесь указывается, что после слога «ом» должен быть конец строки, а перед ним должен идти один или более символ на кириллице.

Вывод будет таким:

./russian1:Златая цепь на дубе том
./russian1:Всё ходит по цепи кругом

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

Поэтому в данной инструкции рассматриваются лишь часть его возможностей.

Номер строки (-n)

С помощью флага -n можно добавить номер строки во время вывода найденных вхождений:

grep -n 'ый$' russian1

Вывод будет таким:

1:У лукоморья дуб зелёный
3:И днём и ночью кот учёный

Поиск без учета регистра (-i)

С помощью флага -i можно искать вхождения, не учитывая регистр символов:

grep -i 'И' russian1

Вывод будет таким:

И днём и ночью кот учёный
Всё ходит по цепи кругом

Мы могли бы не указывать этот флаг:

grep 'И' russian1

В этом случае было бы найдено лишь одно вхождение:

И днём и ночью кот учёный

Поиск по всему слову (-w)

Часто нужно найти только целые слова, а не вхождения указанных символов. Для этого используется флаг -w.

Мы можем модифицировать предыдущий поиск, задействовав сразу два флага:

grep -iw 'И' russian1

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

И днём и ночью кот учёный

Инвертированный поиск (-v)

Результаты поиска можно инвертировать. То есть вывести только те строки, в которых нет указанных вхождений:

grep -v 'И' russian1

Для наглядности можно указать номера строк:

grep -vn 'И' russian1

Консольный вывод будет таким:

1:У лукоморья дуб зелёный
2:Златая цепь на дубе том
4:Всё ходит по цепи кругом

Как видно, в нем отсутствует третья строка — именно в ней и было указанное вхождение.

Несколько регулярный выражений (-e)

Можно использовать несколько регулярных выражений за один поиск. Для этого каждое выражение записывается после флага -e:

grep -e 'ый$' -e 'це' ./*

Таким образом консольный вывод будет представлять собой последовательную комбинацию двух команд:

grep 'ый$' ./*
grep 'це' ./*

Рекурсивный поиск (-r)

Для этого давайте перейдем на уровень выше — в корневой каталог:

cd

Теперь выполним рекурсивный поиск в корневом каталоге:

grep -r 'ый$' ./

Утилита grep найдет вхождения в каталоге на уровень ниже — в папке с текстовыми файлами. Вывод будет следующим:

./files/russian1:У лукоморья дуб зелёный
./files/russian1:И днём и ночью кот учёный

Обратите внимание на адрес найденного файла — теперь он содержит название подкаталога.

Вернемся обратно в папку с файлами:

cd files

Расширенный вывод (-A, -B, -C)

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

С помощью флага -A можно указать количество строк для вывода ПОСЛЕ строки с найденным совпадением:

grep -A1 'ый$' ./*

Вывод будет таким:

./russian1:У лукоморья дуб зелёный
./russian1-Златая цепь на дубе том
./russian1:И днём и ночью кот учёный
./russian1-Всё ходит по цепи кругом

С помощью флага -B можно указать количество строк для вывода ДО строки с найденным совпадением:

grep -B1 'ый$' ./*

Вывод будет таким:

./russian1-Златая цепь на дубе том
./russian1:И днём и ночью кот учёный
./russian1-Всё ходит по цепи кругом

С помощью флага -C можно указать количество строк для вывода ДО и ПОСЛЕ строки с найденным совпадением:

grep -C1 'ый$' ./*

Вывод будет таким:

./russian1:У лукоморья дуб зелёный
./russian1-Златая цепь на дубе том
./russian1:И днём и ночью кот учёный
./russian1-Всё ходит по цепи кругом

Вывод только количества строк (-c)

Есть специальный флаг -c, который вместо всех совпадений выводит только их количество:

grep -c 'ый$' ./*

Консольный вывод будет таким:

./code1:0
./english1:0
./russian1:2

Как видно, отсутствие совпадений тоже показывается в терминале. В данном случае есть только два вхождения в файле с текстом на русском языке.

Обрезанный вывод (-m)

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

grep -m1 'ый$' ./*

Таким образом в консоли будет не этот вывод:

./russian1:У лукоморья дуб зелёный
./russian1:И днём и ночью кот учёный

А более короткая его версия:

./russian1:У лукоморья дуб зелёный

Поиск в нескольких файлах

Поиск в каталогах

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

grep 'su' ./*

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

./code1:const sum = number1 + number2;
./code1:console.log('Сумма чисел ' + number1 + ' и ' + number2 + ' равна ' + sum);
./english1:However little known the feelings or views of such a man may be on his first entering a neighbourhood, this truth is so well fixed in the minds of the surrounding families, that he is considered as the rightful property of some one or other of their daughters.

Можно заметить, что консольный вывод при поиске в директории отличается от консольного вывода при поиске в файле — теперь каждая найденная строка отмечается адресом файла, в котором она записана.

Включение и исключение файлов

Во время поиска в каталогах можно включать и исключать файлы с помощью флагов include и exclude.

Например, можно убрать из предыдущего поиска файл с английским текстом:

grep --exclude 'english1' 'su' ./*

Теперь в терминале появится такое сообщение:

./code1:const sum = number1 + number2;
./code1:console.log('Сумма чисел ' + number1 + ' и ' + number2 + ' равна ' + sum);

Мы могли бы получить тот же самый вывод, включив в поиск только файл с кодом:

grep --include 'code1' 'su' ./*

Важно понимать, что название файла для исключения и включения — тоже регулярное выражение.

То есть можно сделать так:

grep --include '*s*1' ' ' ./*

Эта команда ищет знак пробела только в тех созданных файлах, в названии которых есть буква «s» и которые заканчиваются символом «1».

Исключение каталогов

Помимо файлов, можно исключать и целые каталоги.

Давайте сперва поднимемся на уровень выше:

cd

Теперь выполним рекурсивный поиск в текущем каталоге, указывая папки для исключения с помощью опции exclude-dir:

grep --exclude-dir='files' -R 'su' ./*

В этом случае папка с файлами для поиска будет исключена из консольного вывода.

Вернемся обратно в каталог с файлами:

cd files

Внешний файл с регулярными выражениями

Регулярные выражения для поиска вхождений можно вынести в отдельный файл, а его в свою очередь уже указывать в команде. Иногда это полезно, когда одни и те же регулярные выражения используются слишком.

Для этого создается файл с произвольным именем, внутри которого прописываются выражения:

sudo nano regulars

Каждое регулярное выражение пишется с новой строки:

su
ый$

После чего можно вызвать команду вместе с флагом -f:

grep -f regulars ./*

Консольный вывод будет содержать все строки, в которых есть вхождения указанных выражений:

./code1:const sum = number1 + number2;
./code1:console.log('Сумма чисел ' + number1 + ' и ' + number2 + ' равна ' + sum);
./english1:However little known the feelings or views of such a man may be on his first entering a neighbourhood, this truth is so well fixed in the minds of the surrounding families, that he is considered as the rightful property of some one or other of their daughters.
./regulars:su
./russian1:У лукоморья дуб зелёный
./russian1:И днём и ночью кот учёный

Обратите внимание на эту строку консольного вывода:

./regulars:su

Так как файл с регулярными выражениями мы разместили в той же папке, где и файлы с текстами, и ее же указали в качестве источника поиска, утилита grep нашла вхождение и в файле с регулярным выражением.

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

Исправить это можно с помощью исключения файла с регулярными выражениями:

grep -f regulars --exclude='regulars' ./*
Разверните свой Linux-сервер<br/>в Timeweb Cloud

Заключение

В большинстве UNIX-подобных систем команда grep реализует мощные возможности по поиску текстовой информации в файловой системе ОС.

Помимо этого, команда grep неплохо адаптирована к конвейерам (pipeline) Linux, позволяя обрабатывать не только внешние файлы, но и выводы других консольных команд. Это достигается за счет использования регулярных выражений и конфигурации поиска различными флагами.

Комбинируя все функциональные возможности этой утилиты, можно решать самые разные задачи поиска. Можно сказать, что команда grep — это «перочинный ножик» для поиска информации в операционных системах на базе Linux.

Хотите внести свой вклад?
Участвуйте в нашей контент-программе за
вознаграждение или запросите нужную вам инструкцию
img-server
23 августа 2024 г.
268
12 минут чтения
Средний рейтинг статьи: 5
Пока нет комментариев