【发布时间】:2012-10-12 10:01:28
【问题描述】:
我需要编辑文件中的几行,以便 如果一行以 (av 或 avpgw) 开头,则将其替换为新文本, 否则只需在开头插入新文本。
如何使用 sed 做到这一点?
【问题讨论】:
我需要编辑文件中的几行,以便 如果一行以 (av 或 avpgw) 开头,则将其替换为新文本, 否则只需在开头插入新文本。
如何使用 sed 做到这一点?
【问题讨论】:
我的回答只是对Olaf 的优秀解决方案above 的一个小小的澄清。
如果您使用的是 OSX(对我来说,使用 Catalina,它使用 sed 的 2005 非 GNU 版本),并且您尝试使用他更简洁的基于分号的解决方案(在下面重复,用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 字符是否真的比仅使用额外的 -es 更好,这是值得商榷的。除了大声笑:我发帖主要是因为我想分享这个问题的“根本原因”,这样使用 OS X 的人就不会因为他们的 sed 版本不正确支持 @ 而发疯987654332@ 命令稳健——这只是分号与换行符的问题,仅此而已!
测试文件:
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
【讨论】:
你可以这样做:
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 特定的,为此您可以搜索一般的正则表达式。
【讨论】:
sed 或其他版本。 sed --version 说什么?
这可能对你有用(GNU sed):
sed -r 's/^av(pgw)?.*/replacement/;t;s/^/replacement /' file
【讨论】:
?,这意味着相同的 0 或 1。但如果没有字符串 avpgwpgw * 的机会就可以了。