sed 模式匹配中的奇怪行为

sed 模式匹配中的奇怪行为

以下两个例子是预期的行为。
“xxx2”、“xxx@”都与“xxx。”模式匹配,没有问题。

$ echo abc1xxx2abc3abc4@111 | sed -rn 's/((abc.|xxx.){3}).*/\1/p'
abc1xxx2abc3

$ echo abc1xxx@abc3abc4@111 | sed -rn 's/((abc.|xxx.){3}).*/\1/p'
abc1xxx@abc3

下面的两个例子也是预期的行为。
“xxx@”、“xxxy”均与“xxx”匹配。模式
但接下来的“@”字符与模式不匹配,因此没有输出

$ echo abc1xxx@@abc3abc4@111 | sed -rn 's/((abc.|xxx.){3}).*/\1/p'
no output

$ echo abc1xxxy@abc3abc4@111 | sed -rn 's/((abc.|xxx.){3}).*/\1/p'
no output

但是如果我将上面示例中的“y”更改为“x”,那么
即使下一个字符是“@”,模式也会突然匹配,
我无法理解这种行为

$ echo abc1xxxx@abc3abc4@111 | sed -rn 's/((abc.|xxx.){3}).*/\1/p'
abc1xxxx@abc3abc4

答案1

让我们稍微改变一下你的模式,以便我们可以看到发生了什么(只需添加^.*到开头,以便整个输入行被反向引用替换):

$ echo abc1xxxx@abc3abc4@111 | sed -rn 's/^.*((abc.|xxx.){3}).*/\1/p'
xxx@abc3abc4

所以它匹配xxx@后跟abc3后跟abc4。这是完全合法且符合预期的,因为该模式正在寻找 或 的三个abc.出现xxx.

输出行开头的abc1x永远不会受到模式的影响,因此也永远不会被替换所替换。它只是从输入传递过来的。

相关内容