Board logo

标题: 【出题】30万文件快速替换 [打印本页]

作者: plp626     时间: 2010-3-2 23:59    标题: 【出题】30万文件快速替换

手上现在有30多万htm文件(还有少量的html),这些文件里有相当多的一部分挂马,发现这些挂马的html及htm源文件的最后一行含有mm.aa88567.cn这个网址,

现在,要找出那些挂马的网页(最后一行包含字符串"mm.aa88567.cn”),然后把它的最后一行删掉,

使用工具,windows 自带的常用工具,或者外部工具:perl,sed,。。。(体积大小不超过1M的皆可)

现在求处理速度最快的工具,及其方案(代码)

sed (40K 版本 4.0.7)下载:  http://upload.cn-dos.net/img/1813.rar
perl(369K 版本 5.005_03) 下载:  http://upload.cn-dos.net/img/1814.rar

下面是生产测试文件的bat代码:
@echo off&setlocal enabledelayedexpansion
md test&cd test
echo 正在生产测试文件。。。
for /l %%a in (1 1 2000)do (
(echo ^<html^>
echo ...!random!...
echo ^<... http://mm.aa88567.cn/ ... ^>
)>!random!!time:~-2!!random!.htm
)

for /l %%a in (1 1 3000)do (
(echo ^<html^>
echo ...!random!...
echo dfddfd
)>!random!!time:~-2!!random!!time:~-2!.html
)

set ff=!random!
md %ff%

for /l %%a in (1 1 2000)do (
(echo ^<html^>
echo ...!random!...
echo ^<... http://mm.aa88567.cn/ ... ^>
)>%ff%\!random!!time:~-2!!random!.htm
)

for /l %%a in (1 1 3000)do (
(echo ^<html^>
echo ...!random!...
echo dfddfd
)>%ff%\!random!!time:~-2!!random!!time:~-2!.html
)
[ Last edited by plp626 on 2010-3-4 at 23:00 ]
作者: radem     时间: 2010-3-3 01:46
WIN32的要吗
速度未知
附件 1: 20100303013116751.png (2010-3-3 01:46, 2.68 K, 下载附件所需积分 1点 ,下载次数: 8)



作者: Pierre     时间: 2010-3-3 02:19
试试
for /f "delims=" %%i in ('dir /s /b *.html') do sed -i "${/mm\.aa88567\.cn/d}" "%%i"

[ Last edited by Pierre on 2010-3-3 at 02:23 ]
作者: HAT     时间: 2010-3-3 04:36

sed -i "/mm\.aa88567\.cn/d" *.html

作者: qq330878338     时间: 2010-3-3 14:34
看了下  不简单   只能帮顶了。
作者: plp626     时间: 2010-3-3 15:09
4楼的代码应该是比较快的---- 相比3路没有频繁的启动sed
可是:

用1楼的bat代码生成测试文件在test目录内,于test父目录路径下打开cmd,键入 sed -i "/mm\.aa88567\.cn/d" test\*.html
后,不等几秒钟便出现sed什么内存不能为read的错误

貌似sed最多支持批量处理文件为512个,因为在目录生成了511个临时文件就弹出了这错误对话框,

不知何故,继续关注。。。。

[ Last edited by plp626 on 2010-3-3 at 15:11 ]
作者: tachyon     时间: 2010-3-3 16:06
直接sed速度最快,不要用通过for, for的效率是最低的。 频繁开启&结束sed进程,对系统资源也是极大消耗,估计用不了多久cpu / mem 就out了。

还有,300,000 文件挨个处理速度不会太快的,毕竟牵扯到磁盘操作,不像是在内存里做计算类任务。
作者: tachyon     时间: 2010-3-3 16:10


  Quote:
Originally posted by plp626 at 2010-3-3 15:09:
4楼的代码应该是比较快的---- 相比3路没有频繁的启动sed
可是:

用1楼的bat代码生成测试文件在test目录内,于test父目录路径下打开cmd,键入 sed -i &q ...

这个还是要看sed文档了,如果有同时编辑的文件数目限制,那可以先通过batch
把所有文件按数量划分到若干个目录,之后再依次对各个目录进行sed 处理。
作者: sady2009     时间: 2010-3-3 16:41
现在的内存都很大.
安装个ramdisk .把文件弄到ramdisk 盘中再用批处理. 它的小文件存取速度是非常惊人的. 相对于在内存中执行一样了.
作者: Pierre     时间: 2010-3-3 17:19
直接 *.html的话,通配符匹配到的文件都是以参数形式传递给sed来执行的,所以不能超出某个量数
—— 如果你在shell下这样用sed的话,就会出现
-bash: /bin/sed: Argument list too long
这样的错误
当然,不仅仅是sed这样, awk/grep 等均有此待遇

如果想效率再高点的话,可以切割列表,500个一次送给sed处理

[ Last edited by Pierre on 2010-3-3 at 17:20 ]
作者: Pierre     时间: 2010-3-3 17:27
或者,直接用perl处理,让它循环处理
可惜用得不熟,迟点试着写个解决看看罢。。。
作者: plp626     时间: 2010-3-3 20:42
我对perl也不怎么懂,还真希望有某高人能用一楼提供的perl来试试,

期待中。。。。。
作者: freeants001     时间: 2010-3-4 16:19
贴个自已用的JS文件替换代码,按楼主的要求修改了下。
if(WScript.arguments.length==0)PathSpec=get_path();
else PathSpec=WScript.arguments(0);
fso=new ActiveXObject("Scripting.FileSystemObject");
WshShell=WScript.CreateObject("WScript.Shell");
WshShell.CurrentDirectory=fso.GetParentFolderName(WScript.ScriptFullName);
if(!fso.FolderExists("#ReplacedFiles#"))fso.CreateFolder("#ReplacedFiles#");
WshShell.CurrentDirectory="#ReplacedFiles#"
Main(PathSpec);
WScript.quit();

function Main(FileSpec){
    var fld,fs,fds,f,fd,curdir;
    curdir=fso.GetBaseName(FileSpec);
    if(!fso.FolderExists(curdir))fso.CreateFolder(curdir);
    curdir=fso.GetAbsolutePathName(curdir);   
    WshShell.CurrentDirectory=curdir;
    fld = fso.getfolder(FileSpec);
    fds = new Enumerator(fld.subfolders);
    fs = new Enumerator(fld.files)
    for(;!fs.atEnd();fs.moveNext()){
        f=fs.item();if(f.size==0)continue;
        if(/^html?$/gi.test(fso.getextensionname(f.name).toLowerCase())){
            try{
                var fl=fso.opentextfile(f.path,1);
                var sss=fl.readall();
                fl.close();
            }catch(err){
                WScript.quit();
            }
            var fl=fso.opentextfile(fso.GetBaseName(f.path)+".txt",2,true);
            sss=sss.replace(/.*mm\.aa88567\.cn.*\s*$/,"");
            fl.write(sss);
            fl.close();
        }      
    }
    for(;!fds.atEnd();fds.moveNext()){
        d=fds.item();
        Main(d.path)
        WshShell.CurrentDirectory=curdir
    }
}


function get_path(){
    var objShell = new ActiveXObject("Shell.Application")
    do{
        var objFolder = objShell.BrowseForFolder(0, "请选择文件夹:",0x301,0x11)
        if(objFolder == null)WScript.quit()
        var objPath = objFolder.Self.Path;
        if(/^[a-z]:\\.+$/gi.test(objPath))break;
    }while(true)
    return objPath;
}

作者: freeants001     时间: 2010-3-4 20:18
再来一段AHK脚本
FileSelectFolder, sPath ,,3,请选择你要处理的文件夹:
if not %errorlevel%
{
    IfNotExist,%sPath%_BAK
    {
        MsgBox,4,,没有发现备份,是否创建备份?  
        IfMsgBox Yes
        {
            TrayTip,,正在创建备份 ……,5
            FileCopyDir %sPath% , %sPath%_BAK
        }
    }
    Loop, %sPath%\*.html, , 1  ; Recurse into subfolders.
    {
        FileRead, sText, %A_LoopFileFullPath%   
        sss := RegExReplace( sText ,".*mm\.aa88567\.cn.*\s$", "")
        FileDelete %A_LoopFileFullPath%
        FileAppend %sss%, %A_LoopFileFullPath%
    }

}

loop 2
{
    soundBeep 2500,500
    sleep 500
}

作者: plp626     时间: 2010-3-4 21:23
13楼的代码试了下,速度那时没的说,只是,文件的后缀名统一被改为txt了,那些网页文件,索引的后缀是html,非索引的是htm,

对js不懂,你的代码后缀名不变的情形如何修改?
作者: freeants001     时间: 2010-3-4 21:32
这样可以了
;)
if(WScript.arguments.length==0)PathSpec=get_path();
else PathSpec=WScript.arguments(0);
fso=new ActiveXObject("Scripting.FileSystemObject");
WshShell=WScript.CreateObject("WScript.Shell");
WshShell.CurrentDirectory=fso.GetParentFolderName(WScript.ScriptFullName);
if(!fso.FolderExists("#ReplacedFiles#"))fso.CreateFolder("#ReplacedFiles#");
WshShell.CurrentDirectory="#ReplacedFiles#"
Main(PathSpec);
WScript.quit();

function Main(FileSpec){
    var fld,fs,fds,f,fd,curdir;
    curdir=fso.GetBaseName(FileSpec);
    if(!fso.FolderExists(curdir))fso.CreateFolder(curdir);
    curdir=fso.GetAbsolutePathName(curdir);   
    WshShell.CurrentDirectory=curdir;
    fld = fso.getfolder(FileSpec);
    fds = new Enumerator(fld.subfolders);
    fs = new Enumerator(fld.files)
    for(;!fs.atEnd();fs.moveNext()){
        f=fs.item();if(f.size==0)continue;
        if(/^html?$/gi.test(ext=fso.getextensionname(f.name).toLowerCase())){
            try{
                var fl=fso.opentextfile(f.path,1);
                var sss=fl.readall();
                fl.close();
            }catch(err){
                WScript.quit();
            }
            var fl=fso.opentextfile(fso.GetBaseName(f.path)+"."+ext,2,true);
            sss=sss.replace(/.*mm\.aa88567\.cn.*\s*$/,"");
            fl.write(sss);
            fl.close();
        }      
    }
    for(;!fds.atEnd();fds.moveNext()){
        d=fds.item();
        Main(d.path)
        WshShell.CurrentDirectory=curdir
    }
}


function get_path(){
    var objShell = new ActiveXObject("Shell.Application")
    do{
        var objFolder = objShell.BrowseForFolder(0, "请选择文件夹:",0x301,0x11)
        if(objFolder == null)WScript.quit()
        var objPath = objFolder.Self.Path;
        if(/^[a-z]:\\.+$/gi.test(objPath))break;
    }while(true)
    return objPath;
}
[ Last edited by freeants001 on 2010-3-4 at 22:45 ]
作者: plp626     时间: 2010-3-4 22:22
var fl=fso.opentextfile(fso.GetBaseName(f.path)+".html",2,true);

恐怕不仅仅是将txt改为html这么简单;我不知道获取你代码里那个“f.path”后缀的函数是什么,兄是否可以吧红色的那个html改为它呢?

这些文件大都是htm文件 ,但还有不少html文件(为索引文件)

如果都同一改为html,那么那些本来是htm的文件的链接会失效,在替换的时候,文件名要保持原样。

PS:这30万的网页文件时某个静态网站的所有文件。

[ Last edited by plp626 on 2010-3-4 at 22:26 ]
作者: freeants001     时间: 2010-3-4 22:48
16楼已修改
作者: plp626     时间: 2010-3-4 22:55
我测试了下,16楼的代码只替换test目录里后缀名为html的文件,而htm的文件没有得到替换,这是何故,测试文件用1楼的代码生成
作者: freeants001     时间: 2010-3-4 23:01


  Quote:
Originally posted by plp626 at 2010-3-4 22:55:
我测试了下,16楼的代码只替换test目录里后缀名为html的文件,而htm的文件没有得到替换,这是何故,测试文件用1楼的代码生成

不会吧,我这里测试可以啊。
作者: plp626     时间: 2010-3-4 23:28
16楼的代码正确,是我的原因

试着运行了下,20多万文件替换了8千多文件用时近8分钟(如果总数是1万个文件替换完却用时不到1分钟,不知为何),看来得30*8=240分钟,呀,得4个小时,是当时下载所花时间的一半。

[ Last edited by plp626 on 2010-3-4 at 23:39 ]
作者: plp626     时间: 2010-5-20 13:20
我电脑上就有一个这样的三方工具,直接替换的,老早下载的白杨作品集——fr.exe,速度灰常快,测试了下,10分钟左右全部替换完了
fr *.htm* -s -f:"<scr<script language=javascript src=http://mm.aa88567.cn/index/mm.js></script>" -t:""