21

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

如何使用 sed 做到这一点?

4

3 回答 3

17

你可以这样做:

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 命令摘要

您还可以使用以下命令分隔命令;

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具体,为此您可以搜索一般的正则表达式。

于 2012-10-22T15:02:45.897 回答
1

这可能对您有用(GNU sed):

sed -r 's/^av(pgw)?.*/replacement/;t;s/^/replacement /' file
于 2012-10-22T15:10:24.153 回答
0

我的回答只是对上述Olaf的出色解决方案的一个小小的澄清。

如果您使用的是 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/'

这个问题和解决方案在:MacOS 上的 sed “undefined label”中描述

以下是适用于 OSX 的 Olaf 的“一体化命令”解决方案的一个版本。\n字符是否真的比仅使用 extra 更好是有争议-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
于 2021-04-18T20:18:25.210 回答