Linux查找带有字符串和替换的文件

时间:2012-03-27 22:07:16

标签: linux perl find replace xargs

我有一些网站遭到攻击并感染了恶意软件。

有800多个文件需要更新,每个文件中的字符串完全相同。

我想要做的是找到所有包含恶意软件的文件,然后从文件中删除有问题的字符串。

我发现一些命令行脚本在基本字符串上测试时工作正常:

perl -pi -w -e 's/string_to_find//g;' test-file.php

并且当组合到find命令中时:

找到。 -type f | xargs grep'string_to_find'-sl | xargs perl -pi -w -e's / string_to_find // g;'

现在我的问题是如何处理字符串,这是一个非常长且复杂的字符串:

<?php @error_reporting(0); if (!isset($eva1fYlbakBcVSir)) {$eva1fYlbakBcVSir = "random_string_7365_characters_long";$eva1tYlbakBcVSir = "string_of_encoded_characters";$eva1tYldakBcVSir = "string_of_encoded_characters";$eva1tYldakBoVS1r = "string_of_encoded_characters";$eva1tYidokBoVSjr = "string_of_encoded_characters";$eva1tYldokBcVSjr=$eva1tYldakBcVSir($eva1tYldakBoVS1r);$eva1tYldakBcVSjr=$eva1tYldakBcVSir($eva1tYlbakBcVSir);$eva1tYidakBcVSjr = $eva1tYldakBcVSjr(chr(2687.5*0.016), $eva1fYlbakBcVSir);$eva1tYXdakAcVSjr = $eva1tYidakBcVSjr[0.031*0.061];$eva1tYidokBcVSjr = $eva1tYldakBcVSjr(chr(3625*0.016), $eva1tYidokBoVSjr);$eva1tYldokBcVSjr($eva1tYidokBcVSjr[0.016*(7812.5*0.016)],$eva1tYidokBcVSjr[62.5*0.016],$eva1tYldakBcVSir($eva1tYidokBcVSjr[0.061*0.031]));$eva1tYldakBcVSir = "";$eva1tYldakBoVS1r = $eva1tYlbakBcVSir.$eva1tYlbakBcVSir;$eva1tYidokBoVSjr = $eva1tYlbakBcVSir;$eva1tYldakBcVSir = "string_of_encoded_characters";$eva1tYlbakBcVSir = "string_of_encoded_characters";$eva1tYldakBoVS1r = "string_of_encoded_characters";$eva1tYldakBcVSir = "";$eva1tYldakBoVS1r = $eva1tYlbakBcVSir.$eva1tYlbakBcVSir;$eva1tYidokBoVSjr = $eva1tYlbakBcVSir;} ?>

现在,当我尝试搜索并替换为完整字符串(转义所有特殊字符)时,我得到了这个结果:

Possible unintended interpolation of @error_reporting in string at -e line 1.
Name "main::error_reporting" used only once: possible typo at -e line 1.

是否有可能做我想做的事情或字符串无法捕捉?我需要以不同方式逃避@符号吗? (我带着\逃脱了,但没有用)

任何帮助 - 我是bash和perl的新手

4 个答案:

答案 0 :(得分:1)

\@应该有效,但您也遇到其他问题:<?匹配可选的<,例如,不是序列<?。根据{{​​1}},以下应该有效:

man perlre

perl -pi -w -e 's/\Q<?php \E@\Qerror_reporting...//g' 关闭所有特殊的正则表达式含义,允许您在不引用每个元字符的情况下搜索精确的字符串。 \ E暂时恢复特殊含义,但由于\Q被隔离,因此不会将其解释为数组名称的开头。您必须以相同的方式包围每个@@。当然,请检查这是否正常!祝你好运。

编辑:事实上,我建议您使用简单的脚本替换您的单线程。定义要搜索的字符串,确保不会发生不需要的变量替换(打印出来以确保);禁用$的所有特殊字符以禁用其正则表达式含义;并适用于输入。如果字符串真的完全一样的话就是这样;如果“random_string ...”因地而异,则需要更仔细地构建RE。无论如何,如果你编写一个5行perl脚本,让它在一个文件上工作,然后使用find / xargs方法将其应用到任何地方,它将使你的生活更轻松。

答案 1 :(得分:0)

您可能想要退回到命令行并使用sed。它专为此类问题而打造。这是一个开始的好地方: IBM Developerworks SED by example

答案 2 :(得分:0)

正则表达式具有其他功能,可以使此任务更容易。如果您没有包含以$evalfYl开头的变量的任何有效代码,那么您可以使用更简单的正则表达式,并使用less来转义:

perl -pi -w -e \
's/<\?php \@error_reporting\(0\);if \(!isset(\$evalYl.*?} \?>//g' \
 test-file.php

其中.*?将匹配任何字符,直到下一次出现的“}?&gt;”在字符串中。

答案 3 :(得分:0)

我明白了。声明是正确的,我只是错过了逃避一些角色。

所以在回答我的问题时,答案是:

是 - 使用的方法是正确的,并且可以实现所需的结果 是的 - @符号也必须转义

正确转义字符串,语句正常。