Sed 逃离美元符号

Sed 逃离美元符号,sed,awk,grep,Sed,Awk,Grep,我的.cnf文件中有一行 datadir = /var/lib/mysql 以下内容按预期将其更改为mysql3307 sed -i 's/\/var\/lib\/mysql$/\/var\/lib\/mysql3307/' /etc/my.cnf 但如果我有以下几点: datadir = /var/lib/mysql/ 则以下内容不会按预期更改路径: sed -i 's/\/var\/lib\/mysql\/$/\/var\/lib\/mysql3307/' /etc/my.cnf 我

我的.cnf文件中有一行

datadir = /var/lib/mysql
以下内容按预期将其更改为mysql3307

sed -i 's/\/var\/lib\/mysql$/\/var\/lib\/mysql3307/' /etc/my.cnf
但如果我有以下几点:

datadir = /var/lib/mysql/
则以下内容不会按预期更改路径:

sed -i 's/\/var\/lib\/mysql\/$/\/var\/lib\/mysql3307/' /etc/my.cnf
我想更改mysql3307的路径,其中datadir是/var/lib/mysql(带/或不带/)

更新:

问题是: 上述两个命令都可以在一台服务器上运行,但在另一台服务器上却无法运行

下面的代码如预期的那样工作,但我需要添加$以指示以mysql结尾的行/

sed -i 's/\/var\/lib\/mysql\//\/var\/lib\/mysql3307/' /etc/my.cnf
观察到:

carot符号“^”按预期工作,但行尾符号$不工作。有线索吗

更新:


在使用“dos2unix”命令后,它似乎起作用了。

如果您的目的是只更改具有该特定目录的路径,那么您需要更巧妙一些。您必须在没有尾随
/
的行尾捕捉它,并且您还必须在有尾随
/
的任何地方捕捉它(无论是否为行尾)

但是您不想捕获像
/var/lib/mysqlplus
这样的内容,因为这是一个完全不同的目录

考虑使用扩展正则表达式,并使用不同的分隔符,以便您的命令看起来不像锯齿(
/\/\/\/\/\/\/\/\/\/\/\/\/\/\
)。通过这些更改,以及对正则表达式本身的一个小修改,它可以正常工作:

$ echo '
/var/lib/mysqlplus
/var/lib/mysql/
/var/lib/mysql
/var/lib/mysql/xyz' | sed -E 's|/var/lib/mysql([$/])|/var/lib/mysql3307\1|'

/var/lib/mysqlplus
/var/lib/mysql3307/
/var/lib/mysql
/var/lib/mysql3307/xyz

$
用作文字字符可能需要转义,但不能用作表示字符串结尾的锚点

顺便说一句,如果您使用不同的分隔符,您的正则表达式将更易于阅读,因此您不必在正则表达式中转义
/

sed -i `'s|/var/lib/mysql/|/var/lib/mysql13307/|' /etc/my.cnf

如果您特别希望只更改
datadir
值,则以下命令更合理:
sed-i.bak的|*datadir*=.*datadir=/var/lib/mysql3306/| g'/etc/my.cnf


注意:
-i.bak
在进行更改之前,使用后缀
.bak
备份原始文件。

在字符串中使用带“/”的sed时(例如文件路径),您可能需要使用其他内容作为分隔符,如“:”
sed-i的:/var/lib/mysql$:/var/lib/mysql3307:“/etc/my.cnf
读起来有点好:)我不确定问题出在哪里?我将第二个示例字符串回显到第二个示例sed中,得到了
datadir=/var/lib/mysql3307
Yes。这个问题是错误的。实际上,它们都不在一台服务器上工作,而两个命令都在另一台服务器上工作!