sed 并删除两个模式之间的字符串

sed 并删除两个模式之间的字符串

我在使用 sed 删除两个模式之间的部分字符串时遇到问题。我总是将最后一个 PATTERN-2 排成一行:

测试.txt:

PATTERN-1xxxxPATTERN-2aaa
PATTERN-1xxxxPATTERN-2fffPATTERN-1zzzzPATTERN-2gggPATTERN-1zzzzPATTERN-2
PATTERN-1xxxxPATTERN-2bbb

指令

sed 's/PATTERN-1.*PATTERN-2//g' test.txt

上面的结果是

aaa

bbb

但我想要

aaa
fffggg
bbb

是否可以找到最接近 PATTERN-1 的 PATTERN-2?

答案1

正如 @steeldriver 指出的,如果您有非贪婪的正则表达式,这很容易。如果没有,您可以使用循环来完成,如下所示:

sed ':a;s/PATTERN-2/\n/;s/PATTERN-1.*\n//;ta' test.txt

这是有效的,因为我们知道任何行的中间都没有换行符。它也适用于未出现在任何行中的任何其他字符,例如§

答案2

如果你只想使用 sed 尝试如下

sed 's/PATTERN-1[^P]*PATTERN-2//g' test.txt

答案3

在您的示例中, .* 匹配您想要保留的内容。

您可以捕获该内容并将其替换回来,方法是:

sed 's/PATTERN-1\(.*\)PATTERN-2/\1/g' test.txt

括号之间的所有内容都存储在第一个捕获缓冲区中,并\1替换为该缓冲区的值。

答案4

“最接近”实际上并不是一个 sed 术语。但是,如果序列的重复次数有合理的限制,PATTERN-1.*PATTERN-2您可以对该数字进行硬编码,如下所示:

     $ sed -E 's/(PATTERN-1).*(PATTERN-2)(.*)\1.*\2/\3/g;s/PATTERN-1.*PATTERN-2//g' <<"end"
     PATTERN-1xxxxPATTERN-2aaa
     PATTERN-1xxxxPATTERN-2fffPATTERN-1zzzzPATTERN-2gggPATTERN-1zzzzPATTERN-2
     PATTERN-1xxxxPATTERN-2bbb
     end

     aaa
     ggg
     bbb

请注意,我使用-E扩展正则表达式语法的选项。另请注意,在搜索表达式中,我对 PATTERN-1 和 -2 字符串使用反向引用,只是为了您的舒适。

相关内容