Linux 上的文件中有以下行:
discovery.uri=http://master.navada.com:8800
我们想koko
在 之前添加这个词master
,所以我这样做:
sed –i 's/master/kokomaster/' file
这使:
discovery.uri=http://kokomaster.navada.com:8800
koko
但我们想要的是仅koko
在之前不存在的情况下添加master
。
例如,下次我们运行时
sed –i 's/master/kokomaster/' file
该行将是:
discovery.uri=http://kokokokomaster.navada.com:8800
答案1
sed -i '/kokomaster/!s/master/koko&/' file
首先测试该字符串是否kokomaster
存在于该行,如果不存在,则进行替换。这几乎是“但我们想要的是koko
仅在单词koko
之前不存在时才将单词添加到”的字面翻译。master
sed
替换的替换部分中的&
将会被替换为与模式部分匹配的文本(即master
)。
阅读注释(见下文)后,您可能想要使用更具体的内容,这些内容实际上只会修改 URI 的服务器名称部分,而不是master
其他地方的任何字符串,即使kokomaster
出现(或未出现)在 URI 路径中:
sed -i 's,^\(discovery\.uri=http://\)\(master\),\1koko\2,' file
您甚至可能想要尽可能匹配精确的和满的您想要替换的行,只是为了避免假设的错误:
sed -i 's,^\(discovery\.uri=http://\)\(master\.navada\.com:8800\)$,\1koko\2,' file
如果配置文件是用 JSON 或其他一些众所周知的格式编写的,您将sed
根本不用,但是jq
或者其他一些专门为处理该格式的文件而编写的适当工具。
答案2
使用
sed 's/\(koko\)*master/kokomaster/'
因此master
,任意数量的前面的koko
s 都会被替换。
答案3
你可以多替换一点来避免这个问题:
sed -i sX/masterX/kokomasterX file
这会替换“/master”,因此下次运行它时,不会替换任何内容,因为“/kokomaster”不匹配。
答案4
我使用下面的 awk 命令来执行相同的操作
命令
awk '$0 !~/kokomaster/{gsub("master","kokomaster",$0)}1' filename >file_tmp && mv file_tmp filename
输出
discovery.uri=http://kokomaster.navada.com:8800
discovery.uri=http://kokomaster.navada.com:8800