Sed命令:如果存在,如何替换只是插入?

时间:2012-10-22 14:53:53

标签: linux sed

我需要在文件中编辑几行 如果一行以(av或avpgw)开头,则用新文本替换它们, 否则只需在开头插入新文本。

如何使用sed执行此操作?

3 个答案:

答案 0 :(得分:12)

你可以这样做:

sed -e 's/^avpgw/new text/' -e t -e 's/^av/new text/' -e t -e 's/^/new text/' file

这将模式替换为new text(s ///)并跳转到结尾(t)。否则它会尝试下一个模式。另请参阅sed commands summary

您还可以将命令与;分开:

sed 's/^avpgw/new text/; t; s/^av/new text/; t; s/^/new text/' file

或将命令放在sed命令文件中:

s/^avpgw/new text/
t
s/^av/new text/
t
s/^/new text/

并以这种方式称呼它:

sed -f commandfile file

如果要忽略大小写,请在替换命令的末尾附加i,如s/^av/new text/i中所示。另一种方法是用字符集s/^[aA][vV]/new text/拼出来。但这不是sed特定的,为此你可以搜索一般的正则表达式。

答案 1 :(得分:1)

这可能适合你(GNU sed):

sed -r 's/^av(pgw)?.*/replacement/;t;s/^/replacement /' file

答案 2 :(得分:0)

我的回答只是对 Olaf 出色的解决方案 above 的一个小说明。

如果您使用的是 OSX(对我来说,使用 Catalina,使用的是 2005 年非 GNU 版本的 sed),并且您尝试使用他更简洁的基于分号的解决方案(下面重复,微小的修改以 1/2/3 结尾):

sed 's/^avpgw/new text 1/; t; s/^av/new text 2/; t; s/^/new text 3/' file

...您可能会收到类似于以下内容的错误,因为将 t 命令与 分号 [;](它们是它们与命令的其余部分通过常规的空格隔开:

sed: 1: "s/^avpgw/new text 1/; t ...": undefined label '; s/^av/new text 2/; t; s/^/new text 3/'

这个问题和解决方案在:sed “undefined label” on MacOS

以下是适用于 OSX 的 Olaf 的“多合一命令”解决方案的一个版本。 \n 字符是否真的比仅使用额外的 -e 更好,这是有争议的。大声笑:我发帖主要是因为我想分享这个问题的“根本原因”,这样使用 OS X 的人就不会因为他们的 sed 版本没有正确支持而发疯强大的 t 命令 -- 这只是分号与换行符的问题,仅此而已!

测试文件:

bash-3.2$ cat file
+ cat file
something
avpgw something else
av another thing
text

原始命令,在 OS X 上执行:

bash-3.2$ sed 's/^avpgw/new text 1/; t; s/^av/new text 2/; t; s/^/new text 3/' file

sed: 1: "s/^avpgw/new text 1/; t ...": undefined label '; s/^av/new text 2/; t; s/^/new text 3/'

用换行符代替分号:

bash-3.2$ sed $'s/^avpgw/new text 1/\nt\ns/^av/new text 2/\nt\ns/^/new text 3/' file

new text 3something
new text 1 something else
new text 2 another thing
new text 3text