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

Быть точным

Some text
begin
Some text goes here.
end
Some more text

и я хочу извлечь весь блок, который начинает с, "начинаются" до "конца".

с awk мы можем сделать как awk '/begin/,/end/' text.

Как сделать с grep?

18
задан 18 November 2016 в 04:29

2 ответа

Обновленный 18 ноября 2016 (так как grep поведение изменяется: grep с-P параметром теперь не поддерживает ^ и $, привязки [на Ubuntu 16.04 с ядром v:4.4.0-21-generic]) ( неправильный (не-) фиксируют )

$ grep -Pzo "begin(.|\n)*\nend" file
begin
Some text goes here.  
end

примечание: поскольку другие команды просто заменяют '^' & привязки '$' с привязкой новой строки '\n' ______________________________

С командой grep:

grep -Pzo "^begin\$(.|\n)*^end$" file

, Если Вы хотите, не включают шаблоны, "начинаются" и "заканчиваются" в результате, используют grep с поддержкой Lookbehind и Lookahead.

grep -Pzo "(?<=^begin$\n)(.|\n)*(?=\n^end$)" file

Также можно использовать \K, уведомляют вместо утверждения Lookbehind.

grep -Pzo "^begin$\n\K(.|\n)*(?=\n^end$)" file

\K опция игнорирует все перед сопоставлением с образцом и игнорирует сам шаблон.
\n используемый для стараются не печатать пустые строки от вывода.

Или поскольку @AvinashRaj предполагает, что существуют простые легкие grep как следующее:

grep -Pzo "(?s)^begin$.*?^end$" file

grep -Pzo "^begin\$[\s\S]*?^end$" file

(?s) говорит grep позволять точке соответствовать символам новой строки.
[\s\S] соответствия любой символ, который является или пробелом или непробелом.

И их вывод без включения "начинаются", и "конец" как следует:

grep -Pzo "^begin$\n\K[\s\S]*?(?=\n^end$)" file # or grep -Pzo "(?<=^begin$\n)[\s\S]*?(?=\n^end$)"

grep -Pzo "(?s)(?<=^begin$\n).*?(?=\n^end$)" file

видят полный тест всех команд здесь ( из датированного, поскольку grep поведение с-P параметром изменяется )

Примечание:

^ указывают, что начало строки и $ указывает на конец строки. они добавленные к вокруг "начинаются" и "заканчиваются" к соответствию им, если они являются одними в строке.
В двух командах я вышел $, потому что это также использующий для "Замены Команды" ($(command)), который позволяет выводу команды заменять название команды.

От человека grep:

-o, --only-matching
      Print only the matched (non-empty) parts of a matching line,
      with each such part on a separate output line.

-P, --perl-regexp
      Interpret PATTERN as a Perl compatible regular expression (PCRE)

-z, --null-data
      Treat the input as a set of lines, each terminated by a zero byte (the ASCII 
      NUL character) instead of a newline. Like the -Z or --null option, this option 
      can be used with commands like sort -z to process arbitrary file names.
14
ответ дан 23 November 2019 в 02:13

В случае, если Ваш grep не поддерживает синтаксис жемчуга (-P), можно попытаться присоединиться к строкам, соответствуя шаблону, затем развернув строки снова как указано ниже:

$ tr '\n' , < foo.txt | grep -o "begin.*end" | tr , '\n'
begin
Some text goes here.
end
2
ответ дан 23 November 2019 в 02:13

Другие вопросы по тегам:

Похожие вопросы: