grep - 显示线条直到特定模式

mus*_*ach 13 command-line grep

我在 Ubuntu 16.04 上,我想搜索文件,让我们说“if”,我想输出直到“endif”。该文件可能如下所示

if …
  SOME CODE
endif
Run Code Online (Sandbox Code Playgroud)

我可以用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
    
    Run Code Online (Sandbox Code Playgroud)
  3. 如果我正确解释了建议的解决方案,建议的解决方案仅搜索从行首开始的模式。即使我删除^命令也不起作用。

Zan*_*nna 24

你可以使用sed

sed -n '/if/,/endif/p' myfile
Run Code Online (Sandbox Code Playgroud)
  • -n 在我们要求之前不要打印任何东西
  • /if/ 找到第一行
  • , 继续直到...
  • /endif/ 这是我们想要的最后一行
  • p 打印匹配的行

  • 事实上,`sed` 或(更好!)`awk` 正是为此的工具,作为具有内置开始/结束模式匹配的标准程序。 (2认同)

ste*_*ver 7

传统grep是面向行的。要进行多行匹配,您要么需要通过告诉它您的输入以空值终止来欺骗它吞咽整个文件,例如

grep -zPo '(?s)\nif.*\nendif' file
Run Code Online (Sandbox Code Playgroud)

或者使用更灵活的工具,例如 pcregrep

pcregrep -M '(?s)\nif.*?\nendif' file
Run Code Online (Sandbox Code Playgroud)

或 perl 本身

perl -00 -ne 'print if m/^if.*?endif/s' file
Run Code Online (Sandbox Code Playgroud)

或者,为了以类似 grep 的方式匹配结构化输入,有sgrep

sgrep '"if" .. ("endif") containing "SOME CODE"' file
Run Code Online (Sandbox Code Playgroud)

  • AFAIK,由于各种实现中的行缓冲区大小有限,试图通过指定不存在的(甚至只是非常罕见的)终止符来欺骗`grep` _et al._ 本质上是脆弱和不可移植的。如果使用 GNU 版本,IIRC 不需要太担心,但不是每个人都这样做。无论如何,在我看来,`sed` 或 `awk` 比非标准扩展的 `grep`s 或 `perl` 更适合这类任务:对于简单的“`sed` 101”来说,两者似乎都太复杂了像这样的问题,以及扩展的 `grep`s 可能同样不可移植。 (2认同)