Sed 命令:如果存在如何替换,否则只插入? [重复]

问题描述 投票:0回答:3

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

如何使用 sed 执行此操作?

linux sed
3个回答
22
投票

你可以这样做:

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


由于替换文本始终相同, 另一种方法可能是删除

avpgw
av
, 然后在开头插入
new text

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

请注意,这也会删除前导

avpgwav
。所以这可能是也可能不是您想要的。


1
投票

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

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

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“未定义标签”

下面是 Olaf 的“一体化命令”解决方案的一个版本,适用于 OSX。

\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
© www.soinside.com 2019 - 2024. All rights reserved.