为什么带有“g”修饰符的 sed 不替换所有匹配项

Dan*_*ger 1 bash sed

带有“g”修饰符的 sed 不会替换所有匹配项。

例子:

$ sed -e 's:foo\([^\s]*\):\1 :g' <(echo "hey foobar foobar ")
Run Code Online (Sandbox Code Playgroud)

预期的:

"hey bar bar"
Run Code Online (Sandbox Code Playgroud)

实际的:

"hey bar foobar"
Run Code Online (Sandbox Code Playgroud)

我在这里缺少什么?

Cha*_*ffy 5

\ssed是 POSIX不保证实现的PCRE 扩展;如果不尊重它,你的匹配只会在字母s或反斜杠处停止,而不是在空格处停止。

如果您使用以下命令,您会得到正确的行为:

sed -re 's:foo([^[:space:]]*):\1 :g'
Run Code Online (Sandbox Code Playgroud)

...或者...

sed -e 's:foo\([^[:space:]]*\):\1 :g'
Run Code Online (Sandbox Code Playgroud)

为了更好地了解自己发生了什么,您可以更改替换字符串以在其周围添加符号,以准确查看正在捕获的内容:

$ sed -e 's:foo\([^\s]*\):<\1 >:g' <<<"hey foobar foobar "
hey <bar foobar  >
$ sed -e 's:foo\([^\s]*\):<\1 >:g' <<<"hey foobar foobar s foobar foobar "
hey <bar foobar  >s <bar foobar  >
Run Code Online (Sandbox Code Playgroud)