如果结束表达式存在,则打印 2 个表达式之间的文本 (sed -n)

如果结束表达式存在,则打印 2 个表达式之间的文本 (sed -n)

所以我想显示文件中两个表达式之间的所有文本

文件

ddd
eee
aaa
vvv
bbb
nnn
cdn
dds
aaa
xxx
xxx
xxx

所以用下面的命令

cat $file |sed -n "/aaa/,/cdn/p"

我明白了

aaa
vvv
bbb
nnn
cdn
aaa
xxx
xxx
xxx

哪个是对的。

但是,我只想要开始和结束表达式“之间”的文本。所以如果没有结束表达式,我不想显示文本......

所以我正在寻找一种方法来得到这个结果

aaa
vvv
bbb
nnn
cdn

答案1

$ sed -n '/aaa/,/cdn/ { /aaa/h; //!H; /cdn/ { g; p; }; }' file
aaa
vvv
bbb
nnn
cdn

这使用与您尝试的命令相同的范围,但在该范围内,如果匹配,我们将行保存到保留空间,aaa如果不匹配aaa,则将行追加到保留空间,然后获取保留空间并打印如果匹配的话cdn

这将提取文件中aaa...的“最紧密”区域,其中或(或两者)重复,这意味着像这样的输入cdnaaacdn

111
111
aaa
222
222
aaa
333
333
cdn
444
444
cdn

会给你

aaa
333
333
cdn

...而不是来自第一的 aaa最后的 cdn


另一种表达相同事物但不使用 的方法-n

sed -e '/aaa/,/cdn/!d' -e '/aaa/h' -e '//!H' -e '/cdn/!d' -e g file

答案2

, 这不是,但它比以下更具可读性sed

perl -0nE 'say $& if /\baaa\b.*?\bcdn\b/s' file
aaa
vvv
bbb
nnn

grep -Pzo '(?s)\baaa\b.*?\bcdn\b' file
aaa
vvv
bbb
nnn

查看grep -Pzo

相关内容