sed :有一个范围以最后一次出现的模式结束(贪婪范围)

Che*_*tar 10 sed awk text-processing ed

获取以下文件:

$ cat f1
stu vwx yza
uvw xyz abc
abc def ghi
def ghi jkl
ghi jkl mno
jkl mno pqr
mno pqr stu
pqr stu vwx
stu vwx yza
Run Code Online (Sandbox Code Playgroud)

要打印从包含GNU的第一行abc到包含GNU 的第一行的所有行:mnosed

$ sed -n '/abc/,/mno/p' f1
uvw xyz abc
abc def ghi
def ghi jkl
ghi jkl mno
Run Code Online (Sandbox Code Playgroud)

我怎样才能打印所有行,直到最后一行包含mno,例如我怎样才能得到以下结果:

uvw xyz abc
abc def ghi
def ghi jkl
ghi jkl mno
jkl mno pqr
mno pqr stu
Run Code Online (Sandbox Code Playgroud)

换句话说,有没有办法让GNUsed的范围选择变得贪婪?

更新

在我的设置中:

  • 如果mno丢失,它应该打印出所有内容,直到文件末尾。
  • mno不能发生在第一个之前abc
  • 总是至少有一个abc, 和abc永远mno不会在同一行

编辑 我刚刚在开头添加了一条虚拟stu vwx yza行,以便文件不以包含的行开头abc(以避免从第一行开始的解决方案 - 它们应该从其中包含的第一行开始abc

Ini*_*ian 5

awk如果有的话你可以使用。您可以标记模式开始和模式停止的行,并在文件的一次传递中打印这些行(涉及存储从第一行开始到abc缓冲区中最后一行的行)

awk '/abc/ && !start {
  start = NR
}
/mno/ {
  stop = NR
}
start { line[NR] = $0 }
END {
  if ( !stop ) {
    stop = NR
  }
  for ( s = start; s <= stop; s++ )
    print line[s]
}' file
Run Code Online (Sandbox Code Playgroud)

请注意,当起始图案不存在时,这将不起作用,仅打印一系列空白行。


nez*_*dka 5

sed '/abc/,$!d;0,/mno/b;:1;/mno/b;$d;N;b1' file
Run Code Online (Sandbox Code Playgroud)

工作算法:
使用两个地址范围。
第一个/abc/,$!d;删除第一个模式匹配之前的所有内容。
第二个0,/mno/b;直到与模式匹配为止/mno/,将每个行缓冲区(模式空间)发送到绕过剩余脚本的输出,从而防止在文件中找不到模式时删除。
脚本的其余部分:1;/mno/b;$d;N;b1循环工作。在编辑器缓冲区中,行会被追加,直到出现模式匹配为止。如果/mno/遇到模式,整个缓冲区将被发送到输出,绕过脚本的其余部分。如果没有匹配,则删除缓冲区的最后一行。