grep - показывать линии до определенного шаблона

Я нахожусь на Ubuntu 16.04, и я хочу искать файлы, скажем, "если", и я хочу выводить до "endif". Файл может выглядеть так

if …
  SOME CODE
endif

Я могу сделать это с grep -A9 if my_file | grep -B9 endif, Это не работает, если предложение if больше 9 и несколько предложений if находятся в одном файле и если первая команда grep содержит несколько предложений if. Опция -m1 во втором grep не помогает. Вложенные предложения "if" можно игнорировать. У кого-нибудь есть идея, может быть, не с grep?

Разница с тем, как я grep для нескольких шаблонов на нескольких строках?

  1. Вопрос требует решения с grep на который уже ответили в вопросе: grep -A9 if my_file | grep -B9 endif, Решение не работает в моем случае, но будет работать в случае другого вопроса.

  2. Предложенные решения grep другого вопроса не работают (с Ubuntu?): grep: ein nicht geschütztes ^ oder $ wird mit -Pz nicht unterstützt. что-то вроде grep: a not protected ^ or $ is not supported with -Pz, Я использую следующее:

    root:/tmp# cat file
    Some text
    begin
    Some text goes here.  
    end
    Some more text 
    root:/tmp# grep -Pzo "^begin\$(.|\n)*^end$" file
    grep: ein nicht geschütztes ^ oder $ wird mit -Pz nicht unterstützt
    
  3. Предлагаемые решения ищут только шаблон, начинающийся в начале строки, если я правильно интерпретирую предложенное решение. Даже если я удалю ^ команда не работает.

3 ответа

Решение

Ты можешь использовать sed для этого:

sed -n '/if/,/endif/p' myfile
  • -n не печатайте ничего, пока мы не попросим об этом
  • /if/ найти первую строку с этим
  • , продолжай, пока...
  • /endif/ это последняя строка, которую мы хотим
  • p напечатать совпадающие линии

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

grep -zPo '(?s)\nif.*\nendif' file

или используйте более гибкий инструмент, такой как pcregrep

pcregrep -M '(?s)\nif.*?\nendif' file

или сам Perl

perl -00 -ne 'print if m/^if.*?endif/s' file

В качестве альтернативы, для сопоставления структурированного ввода в стиле grep, есть sgrep

sgrep '"if" .. ("endif") containing "SOME CODE"' file

Решение awk может выглядеть так: awk '/if/,/endif/' file

Конечно, это похоже на решение с sed,

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