我正在尝试替换数据库中的字符串。我在下面找到了可能的解决方案。使用#
or%
对我有效,但对/
and无效|
。谁能解释为什么前两个有效以及它们之间有什么区别?
find . -type f -name 'file.sql' -exec sed -i '' s#http://a.com#http://b.com#g {} +
find . -type f -name 'file.sql' -exec sed -i '' s%http://a.com%http://b.com%g {} +
find . -type f -name 'file.sql' -exec sed -i '' s/http://a.com/http://b.com/g {} +
find . -type f -name 'file.sql' -exec sed -i '' s|http://a.com|http://b.com|g {} +
答案1
sed的替换命令通常用作命令、搜索字符串、替换字符串和任何标志/
之间的分隔符。s
但是,如果搜索字符串或替换字符串中的任何一个可能包含/
,那么人们会将分隔符更改为以下字符:不是在任一字符串中。
当您告诉 sed 使用空字符串作为备份扩展名时,您收到了来自 sed 的另一个错误;因为您没有使用扩展,所以不要放入空引号。(注意:这仅适用于 GNU sed。如果您使用的是 BSD sed,例如在 Mac 上,那么您做需要空字符串来指定没有备份扩展名。)
Sed 不关心分隔符是什么,但你周围的 shell 可能会关心。
该|
符号引入了管道。要将其用作分隔符,您必须以某种方式引用它以保护它们免受 shell 的影响。
该#
符号可能会根据您的 shell 引入注释字符串(如果 是#
单词的第一个字符,bash 仅开始注释),因此最好安全起见并引用它。
由于您的数据包含/
字符,因此您需要使用不同的分隔符,或者转义/
搜索和替换字符串中的每个实例。这导致了所谓的牙签倾斜综合征由于 的外观难以阅读\/
。
因此,你需要类似的东西:
find . -type f -name 'file.sql' -exec sed -i -e 's#http://a.com#http://b.com#g' {} +
或者
find . -type f -name 'file.sql' -exec sed -i -e 's|http://a.com|http://b.com|g' {} +
或者
find . -type f -name 'file.sql' -exec sed -i -e "s|http://a.com|http://b.com|g" {} +
或者
find . -type f -name 'file.sql' -exec sed -i -e 's/http:\/\/a.com/http:\/\/b.com/g' {} +