Как найти совпадения шаблонов в нескольких строках с помощью 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