删除包含匹配项的第一行之前的所有行?

sta*_*cko 12 text-processing

使用正则表达式字符串,如何删除包含匹配项的第一行之前的所有行?例如,我该如何改变这一点:

lost
load
linux
loan
linux
Run Code Online (Sandbox Code Playgroud)

进入这个:

linux
loan
linux
Run Code Online (Sandbox Code Playgroud)

我试过:

echo "lost
load
linux
loan
linux" | sed -e 's/.*^li.*$//g'
Run Code Online (Sandbox Code Playgroud)

但它返回这个,没有改变任何东西:

lost
load
linux
loan
linux
Run Code Online (Sandbox Code Playgroud)

我想让它工作,以便在没有匹配时它不会输出任何内容。

cuo*_*glm 20

一种方式,POSIXly:

$ echo "lost
load
linux
loan
linux" | sed -e/linux/\{ -e:1 -en\;b1 -e\} -ed
Run Code Online (Sandbox Code Playgroud)

或更短:

sed -n '/linux/,$p'
Run Code Online (Sandbox Code Playgroud)

甚至更短:

sed '/linux/,$!d'
Run Code Online (Sandbox Code Playgroud)

对于想知道为什么我更喜欢较长版本而不是较短版本的读者,较长版本只会对文件的其余部分执行 i/o,而如果第二个地址是正则表达式,则使用范围会影响性能,并且正则表达式试图匹配超过必要的。

考虑:

$ time seq 1000000 | sed -ne '/^1$/{' -e:1 -en\;b1 -e\}
=====
JOB sed -e '/^1$/,$d'
87%    cpu
0.11s real
0.10s user
0.00s sys
Run Code Online (Sandbox Code Playgroud)

和:

$ time seq 1000000 | sed -e '/^1$/,/1000000/d'
=====
JOB sed -e '/^1$/,/1000000/d'
96%    cpu
0.24s real
0.23s user
0.00s sys
Run Code Online (Sandbox Code Playgroud)

你可以看到两个版本之间的不同。使用复杂的正则表达式,会有很大的不同。