Поиск по сайту:

Как найти совпадения шаблонов в нескольких строках с помощью grep


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

Сопоставление нескольких новых строк с помощью grep

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

awk '/from/,/to/' file
sed -n '/from/,/to/p' file

Это все еще возможно сделать в grep, однако эта команда очень неуклюжа.

grep -Pz '(?s)from.*n.*to' test

Это делает несколько вещей:

  • -P Включает Perl-совместимое регулярное выражение.
  • -z помещает весь файл в одну строку с «нулевыми байтами» вместо новой строки. Это позволяет grep обрабатывать все это как одну строку.
  • (?s) включает PCRE_DOTALL, что делает символ . соответствующим любому символу, включая символы новой строки.
  • from – начальное совпадение.
  • .*n.* сопоставляет все до to, что является конечным совпадением.

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

Использование вместо этого pcre2grep (Perl-совместимый grep)

Обычный grep – не лучший инструмент для этой работы, и есть альтернатива, называемая pcre2grep , которая включает в себя поддержку Perl-совместимых регулярных выражений из коробки и способна очень легко сопоставить многострочное регулярное выражение.

Вероятно, он установлен в вашей системе, но если это не так, вы можете получить его в своем менеджере пакетов:

sudo apt install pcre2-utils

Затем вам просто нужно запустить его с параметром -M .

pcre2grep -M 'from(n|.)*to' file

Обратите внимание, что для этого по-прежнему требуется, чтобы вы сопоставляли «новую строку или любой символ» вручную с (n|.)* . Кроме того, вы можете использовать трюк (?s), чтобы включить PCRE_DOTALL и заставить символ точки соответствовать новой строке.

pcre2grep -M '(?s)from.*to' file