从文件中删除文本块:sed?

时间:2010-12-27 20:22:39

标签: apache bash .htaccess mod-rewrite sed

攻击发生后,我需要删除添加到我网站上的.htaccess文件中的4行文本,并且认为SED是可行的方法,但无法看到多次尝试的尖顶。

添加的行是

RewriteEngine On
RewriteCond %{HTTP_REFERER} ^http://
RewriteCond %{HTTP_REFERER} !%{HTTP_HOST}
RewriteRule . http://targeturlhere.net/%{REMOTE_ADDR}

我设法创建脚本以删除仅包含这些行的添加的htaccess文件,但是对于附加了该文件的现有htaccess文件,我必须编辑该文件而不能删除它。我不能一行一行地删除,也不能使用“RewriteEngine On”作为开始标记,因为此指令“RewriteEngine On”有时在文件的其他地方是合法的。

在大多数情况下,这些行是最后一行,但我想在其他文件中它们可能位于中间,所以我试图删除那个块 - 并且有一个我可以在类似情况下重用的脚本。

(编辑:我的4行彼此相差,介于两者之间没有空白行,但这里的编辑器似乎没有显示断行线,或者一行添加空行)

任何提示或提示?感谢。

2 个答案:

答案 0 :(得分:1)

如果您无法触发'RewriteEngine On'行(因为它偶尔合法使用),那么'sed'可能不是该作业的正确工具。我使用Perl(测试代码如下):

my $file;
do { local $/; $file = <>; }; # Slurp!

$file =~ s{
            RewriteEngine \s On \n
            RewriteCond \s %{HTTP_REFERER} \s [\^]http:// \n
            RewriteCond \s %{HTTP_REFERER} \s !%{HTTP_HOST} \n
            RewriteRule \s \. \s http://targeturlhere\.net/%{REMOTE_ADDR} \n
          }{}gmsx;

print $file;

文件被插入内存;然后删除您不想要的数据(重复,以防其中一个文件被多次修改),然后将残留物写入标准输出。 gmsx修饰符可以:

  • g - global
  • m - multiline
  • s - sed-like
  • x - 扩展(忽略空格 - 使用\s(或\s+)来匹配实际的空白区域。

这是为了一次处理一个文件(每次调用脚本)。如果你小心的话,可以让它在命令行上处理多个文件并覆盖原件等;问题领域是“啜食”操作。代码假设您想要将所有文件读入内存并进行处理 - 这是正确的,因为您需要匹配多行。


评论问:

  

[我]已经有一个工作bash脚本列出并扫描托管网站,然后删除只包含那些行的文件,我等着添加该编辑功能。我现在可以在该脚本中使用Perl,还是通过调用它?

如果您可以确定该文件包含的材料不仅仅是您需要删除的四行,那么您可以从脚本内部调用Perl来处理该文件:

  • 保存我在文件fixit.pl中显示的代码:
    • 添加shebang line #!/usr/bin/env perl
    • 为了获得良好的纪律,请考虑在shebang之后和代码之前添加use strict;use warnings;。在这种情况下,它没有区别(代码是干净的),但如果你正在进行更改,请包含这些行。我这样做 - 但我知道我很容易犯错。
    • 使其可执行,并在PATH的目录中,或知道其位置。
  • 在您的shell脚本中:

    ...
    else
        fixit.pl $file > $tmp.1
        mv $tmp.1 $file
    fi
    

您可能有其他方法可以做到这一点,但它只需要那么复杂。我假设您已正确初始化变量tmp

tmp=${TMPDIR:-/tmp}/fixit.$$

您可能希望包含陷阱以确保清理文件:

trap "rm -f $tmp.?; exit 1" 0 1 2 3 13 15
...code as above...
rm -f $tmp.?
trap 0
exit 0

第一个陷阱线捕获信号1(HUP),2(INT),3(QUIT),13(PIPE)和15(TERM),以及它自己的任何shell退出(0),并执行给定命令(删除临时文件并以失败状态退出)。迷路rm -f行确保文件丢失; trap 0取消了“shell自行退出”的陷阱,exit 0成功退出。这意味着您可以中断处理并且不会遗留任何杂散文件 - 这是创建临时文件的任何shell脚本的良好实践。

或者,您可以使用:

perl -i.bak fixit.pl $file

这将使用原始文件创建文件名“$ file.bak”,输出将转到原始文件名“$ file”。这样可以避免使用陷阱等。如果您不想要备份文件,则从命令行中省略“.bak”。

答案 1 :(得分:0)

sed '1{N;N};N;\|\nRewriteRule . http://targeturlhere.net/%{REMOTE_ADDR}$|d;P;D' inputfile

这将查找四个集合的最后一行,当它找到时,它会删除它们。它通过所有其他行。

您可以添加-i选项(sed -i ...)以使其修改文件。您可以添加可选的备用扩展程序,以使其备份原始文件(sed -i .bak ...)。