grep由两个关键线分隔的文本块

lau*_*ent 5 grep textblock match

我有一个文本文件,其中包含大致格式如下的文本块:

Beginning of block
...
...
...
.........some_pattern.......
...
...
End of block

Beginning of block
...
... etc.
Run Code Online (Sandbox Code Playgroud)

这些块可以有任意数量的行,但始终以两个分隔符开头.我想做的是匹配"some_pattern"并将整个块打印到stdout.通过上面的例子,我只会得到这个:

Beginning of block
...
...
...
.........some_pattern.......
...
...
End of block
Run Code Online (Sandbox Code Playgroud)

我试过这样的事但没有成功:

grep "Beginning of block\n.*some_pattern.*\n.*End of block"
Run Code Online (Sandbox Code Playgroud)

知道怎么用grep做这个吗?(或者可能使用其他工具)

fed*_*qui 9

我猜awk对此更好:

awk '/Beginning of block/ {p=1};
     {if (p==1) {a[NR]=$0}};
     /some_pattern/ {f=1};
     /End of block/ {p=0; if (f==1) {for (i in a) print a[i]};f=0; delete a}' file
Run Code Online (Sandbox Code Playgroud)

说明

它只是在p标志为"活动"并且some_pattern匹配时打印:

  • 当它找到时Beginning of block,然后生成变量p=1并开始在数组中存储行a[].
  • 如果找到some_pattern,则将标志设置f为1,以便我们知道已找到模式.
  • 当它发现End of block它重置时p=0.如果some_pattern自上次发现以来Beginning of block,则打印所有已存储的行.最后清除[]并重置f; 当我们再次遇到时,我们将有一个新的开始Beginning of block.

其他测试

$ cat a
Beginning of block
blabla
.........some_pattern.......
and here i am
hello
End of block

Beginning of block
...
... etc.
End of block
$ awk '/Beginning of block/ {p=1}; {if(p==1){a[NR]=$0}}; /some_pattern/ {f=1}; /End of block/ {p=0; if (f==1) {for (i in a) print a[i]}; delete a;f=0}' a
Beginning of block
blabla
.........some_pattern.......
and here i am
hello
End of block
Run Code Online (Sandbox Code Playgroud)


dev*_*ull 6

以下内容可能适合您:

sed -n '/Beginning of block/!b;:a;/End of block/!{$!{N;ba}};{/some_pattern/p}' filename
Run Code Online (Sandbox Code Playgroud)