第二条“测试”线不应该也被更换吗?我该如何编写命令来替换所有“测试”?
$ sed 's/test/toast/' texttest.txt
toast file test file hahahaha 1
toast file test file hahahaha 2
答案1
好的,我知道了 …
g 替换正则表达式的所有非重叠匹配项,而不仅仅是第一个匹配项。
$ sed 's/test/toast/g' texttest.txt
toast file toast file hahahaha 1
toast file toast file hahahaha 2
答案2
正如您已经发现的,s/test/toast/
只会将test
每行中第一次出现的“”替换为“ toast
”。要使 sed 将所有不重叠的“ test
”替换为“ toast
”,您需要附加全局替换标志g
到替换命令,如下所示:
$ echo 'This test is a test.' | sed 's/test/toast/g'
This toast is a toast.
请注意,该g
标志仅处理非重叠替换,例如会将“ testest
”变成“ toastest
”,而不是变成“ toastoast
”:
$ echo 'This test is the testest test.' | sed 's/test/toast/g'
This toast is the toastest toast.
如果你做想要重叠替换,这可以是使用循环解决:
$ echo 'This test is the testest test.' | sed ':loop; s/test/toast/; t loop'
This toast is the toastoast toast.
诗。;
如上所述,用作命令分隔符是 GNU sed 的一项功能。对于 BSD sed(例如在 MacOS 上),您需要使用文字换行符或多个-e
参数:
$ echo 'This test is the testest test.' | sed ':loop
s/test/toast/
t loop'
This toast is the toastoast toast.
$ echo 'This test is the testest test.' | sed $':loop\n s/test/toast/\n t loop'
This toast is the toastoast toast.
$ echo 'This test is the testest test.' | sed -e ':loop' -e 's/test/toast/' -e 't loop'
This toast is the toastoast toast.
(所有这些也适用于 GNU sed。第二个版本,带有$''
,依赖于某些 shell 的特征,例如 bash 和 zsh,并且可能需要引用 sed 代码本身中出现的任何反斜杠。)