用sed替换包含特殊字符的字符串

时间:2011-09-16 11:29:59

标签: regex sed escaping replace

我在这里和其他地方看了很多关于这个主题的帖子,但是所提供的解决方案似乎都不适合我。我需要在特定文件夹中的所有文件中用另一个字符串(包含正确的PHP代码)替换一个字符串(其中包含错误的无意义的PHP代码)。我知道使用sed时唯一需要转义的字符是&符号,反斜杠,以及用作分隔符的任何字符。

我想搜索的字符串是:

$arguments = func_get_args();$numargs = func_num_args();for($i=1; $i < $numargs; $i++){$arguments[$i] = $arguments = func_get_args();$arguments[$i];}

我要替换它的字符串是:

$arguments = func_get_args();$numargs = func_num_args();for($i=1; $i < $numargs; $i++){$arguments[$i] = &$arguments[$i];}

我尝试了很多变化,但无法让它发挥作用。我认为以下命令应该工作(但不是)。

find /folder/to/search -name Function.php -type f -exec sed -i 's|$arguments = func_get_args();$numargs = func_num_args();for($i=1; $i < $numargs; $i++){$arguments[$i] = $arguments = func_get_args();$arguments[$i];}|$arguments = func_get_args();$numargs = func_num_args();for($i=1; $i < $numargs; $i++){$arguments[$i] = \&$arguments[$i];}|' {} \;

这让我疯了 - 任何帮助都会非常感激!

2 个答案:

答案 0 :(得分:4)

我终于找到了正确的语法。与我读过的所有建议相反,我需要摆脱美元符号并在两个表达式中打开方括号(但不是紧密的方括号,也不是弯曲的括号)。所以这是最终适合我的命令:

find /folder/to/search -name Function.php -type f -exec sed -i 's/\$arguments\[\$i] = \$arguments = func_get_args();\$arguments\[\$i];/\$arguments\[\$i] = \&\$arguments\[\$i];/' {} \;

再次感谢那些回复的人。

答案 1 :(得分:2)

  

据我所知,使用sed时唯一需要转义的字符是&符号,反斜杠,以及用作分隔符的任何字符

搜索表达式不正确。这是一个正则表达;对于文字匹配,你需要逃避所有的正则表达式特殊项目,即至少s%\([][^$.\*]\)%\\\1%g(关闭袖口 - 我可能错过了一些,和/或你的sed可能与我的不同)。幸运的是,这很容易以编程方式进行,例如,与sed - 只是要小心,这样你就不会感到困惑。

替换字符串是一个文字字符串,但反向引用除外,因此对于该部分,您的语句为真。

#!/bin/sh
from=`sed 's%[][^$.\*]%\\\&%'<<'____HERE'
$arguments = func_get_args();$numargs = func_num_args();for($i=1; $i < $numargs; $i++){$arguments[$i] = $arguments = func_get_args();$arguments[$i];}
____HERE`
to=`cat<<'____THERE'
$arguments = func_get_args();$numargs = func_num_args();for($i=1; $i < $numargs; $i++){$arguments[$i] = \&$arguments[$i];}
____THERE`
find /folder/to/search -name Function.php -type f -exec sed -i "s|$from|$to|" {} \;