用sed删除长字符串

时间:2017-02-16 18:38:28

标签: php bash sed

我的一个网站感染了一些恶意代码。代码仅添加到所有PHP文件的第一行,如下所示:

<?php $ulhmjwklj = '#-#O#-#N# .......xqxe-1; ?> /*BEGIN LEGIT CODE HERE*/ <?php....

恶意代码是数千个字符长,有很多特殊字符和间距,所以我尝试创建一个脚本来删除它:

for i in $(find . -name \*.php); do
  sed -i -E "s/<\?php\s$ulhmjwklj.*\?>//" $i;
  echo $i;
done;

sed命令将正确删除恶意代码,同时在第一行留下合法代码,但随后在所有后续行中删除所有<?php ... ?>代码。所以我尝试改变sed命令只在第一行搜索/替换:

for i in $(find . -name \*.php); do
  sed -i -E "1s/<\?php\s$ulhmjwklj.*\?>//" $i;
done;

现在sed命令只会在每个文件的第一行运行,但它也会删除在恶意代码之后直接附加到第一行的任何合法PHP标记。

有人可以解释一下我在哪里出错吗?

1 个答案:

答案 0 :(得分:0)

The results of find should not be put through a loop。而且,正如我在评论中提到的,$是Bash和正则表达式的特殊字符,因此必须进行适当的处​​理。

最后,正如评论中提到的jm666,.*是贪婪的,因此.*?将搜索限制为尽可能小。但是this won't work in sed所以我们需要使用perl代替:

find . -name '*.php' -print -exec perl -p -i -e 's/<\?php \$ulhmjwklj.*?\?>//' {} \;