This question already has an answer here:
Using different delimiters in sed commands and range addresses

(1个答案)


4年前关闭。




我在弄清楚如何使用sed来搜索和替换文本文件/中包含/etc/myconfig字符的字符串时遇到了麻烦。

例如,在我现有的文本文件中,我有:
myparam /path/to/a argB=/path/to/B xo

我希望将其替换为:
myparam /path/to/c argB=/path/to/D xo

我试图在bash中执行此操作:
line='myparam /path/to/a argB=/path/to/B xo'
line_new='myparam /path/to/c argB=/path/to/D xo'
sed -i 's/$line/$line_new/g' /etc/myconfig

但是什么也没发生。

尝试中
grep -rn "$line" /etc/myconfig

确实返回了'myparam /path/to/a argB=/path/to/B xo'

表达我的sed命令以执行此搜索并替换并正确处理/命令的正确方法是什么? (我认为字符串中的/字符是给我带来问题的字符,因为我使用了类似的sed命令来毫无问题地搜索和替换文本文件中的另一行,并且该行没有/字符。

最佳答案

不要逃避反斜杠;您会混淆自己的。在s命令后使用未在文本中出现的其他符号(在下面的示例中,我使用%):

line_old='myparam /path/to/a argB=/path/to/B xo'
line_new='myparam /path/to/c argB=/path/to/D xo'
sed -i "s%$line_old%$line_new%g" /etc/myconfig

同样,将整个字符串用双引号引起来;使用单引号意味着sed看到$line(在原始语言中)而不是扩展值。在单引号内,没有扩展,也没有元字符。如果您的文本几乎可以包含任何纯文本字符,请使用控制字符(例如,control-A或control-G)作为分隔符。

请注意,此处使用-i可以反射(reflect)问题中的内容,但前提是使用GNU sed。 BSD sed(也在Mac OS X上找到)需要后缀。您可以使用sed -i '' …原位替换;不适用于GNU sed。要在两者之间可移植,请使用-i.bak;两者均可使用-但会为您提供一个可能要删除的备份文件。其他Unix平台(例如AIX,HP-UX,Solaris)可能具有sed的变体,它们根本不支持-i sed 的POSIX规范不需要它。

10-02 11:18
查看更多