我的一位朋友(他不喜欢强密码......)让他的服务器被黑了,我正试图帮助他。
基本上,服务器上的很多php文件都在第一行的两个php标签之间添加了很多东西。
这样的事情:
1. <?php lots-Of-Stuff-I-Can-Target-Easily-With-Grep ?><?php
2. Line 2 and beyond, the file is unchanged.
&#13;
所以我的问题是:有没有办法通过grep - 或其他东西 - 只是针对第一个php标签,其间的一切都删除它?在上面的例子中,在第1行:所有但是第二个打开php标记。
我知道我可以将第1行作为目标,只需用开放的php标签替换,但为了避免任何问题,我更喜欢目标并删除我想要的确切内容。
有太多文件可以手工完成。有什么想法吗?
答案 0 :(得分:1)
我完全同意Ben Hillier的评论。 (我的意思是特别是备份的部分,因为我对PHP知之甚少。)但是......
可以使用以下 sed 命令:
sed 's/^<?php .* ?>\(<?php.*\)$/\1/'
或者,可以使用 awk :
完成awk '/<\?php .* \?><\?php/ { $0 = gensub(/^<\?php.*\?>(<\?php.*)$/, "\\1", 1, $0) }{ print }'
或附加条件NR==1
以确保测试/替换仅在第一行完成:
awk 'NR==1 && /<\?php .* \?><\?php/ { $0 = gensub(/^<\?php.*\?>(<\?php.*)$/, "\\1", 1, $0) }{ print }'
其中一个命令(巧妙地与find
结合使用)应该可以胜任。
请注意 sed 与 awk 所需的明显转义。
而且,正如Ben Hillier已经建议的那样:不要忘记之前备份。
演示:
$ echo '<?php lots-Of-Stuff-I-Can-Target-Easily-With-Grep ?><?php' \
> | sed 's/^<?php .* ?>\(<?php.*\)$/\1/'
<?php
$ echo '<?php' | sed 's/^<?php .* ?>\(<?php.*\)$/\1/'
<?php
$ echo '<?php lots-Of-Stuff-I-Can-Target-Easily-With-Grep ?><?php' | awk '/<\?php .* \?><\?php/ { $0 = gensub(/^<\?php.*\?>(<\?php.*)$/, "\\1", 1, $0) }{ print }'
<?php
$ echo '<?php' | awk '/<\?php .* \?><\?php/ { $0 = gensub(/^<\?php.*\?>(<\?php.*)$/, "\\1", 1, $0) }{ print }'
<?php
$ echo '<?php lots-Of-Stuff-I-Can-Target-Easily-With-Grep ?><?php' | awk 'NR==1 && /<\?php .* \?><\?php/ { $0 = gensub(/^<\?php.*\?>(<\?php.*)$/, "\\1", 1, $0) }{ print }'
<?php
$ echo '<?php' | awk 'NR==1 && /<\?php .* \?><\?php/ { $0 = gensub(/^<\?php.*\?>(<\?php.*)$/, "\\1", 1, $0) }{ print }'
<?php
$ cat >test.txt <<EOF
> <?php lots-Of-Stuff-I-Can-Target-Easily-With-Grep ?><?php
> // contents
> // contents
> // contents
> ?>
> EOF
$ cat test.txt | sed 's/^<?php .* ?>\(<?php.*\)$/\1/'
<?php
// contents
// contents
// contents
?>
$ cat test.txt | awk '/<\?php .* \?><\?php/ { $0 = gensub(/^<\?php.*\?>(<\?php.*)$/, "\\1", 1, $0) }{ print }'
<?php
// contents
// contents
// contents
?>
$ cat test.txt | awk 'NR==1 && /<\?php .* \?><\?php/ { $0 = gensub(/^<\?php.*\?>(<\?php.*)$/, "\\1", 1, $0) }{ print }'
<?php
// contents
// contents
// contents
?>
$
最后但并非最不重要的是人类读者的awk脚本:
# catch 1st line with a duplicated "<?php"
NR==1 && /<\?php .* \?><\?php/ {
# replace the line by everything including and after 2nd "<?php"
$0 = gensub(/^<\?php.*\?>(<\?php.*)$/, "\\1", 1, $0)
}
{ print } # print any line