中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 会员 | 搜索 | 上传 | 帮助 »
中国DOS联盟论坛 » DOS批处理 & 脚本技术(批处理室) » [原创]用批处理查找符合时间范围的文件
« [1] [2] »
作者:
标题: [原创]用批处理查找符合时间范围的文件 上一主题 | 下一主题
无奈何
荣誉版主





积分 1338
发帖 356
注册 2005-7-15
状态 离线
『楼 主』:  [原创]用批处理查找符合时间范围的文件

[原创]用批处理查找符合时间范围的文件
        起因:
        看到 shijianxin 兄的提问,问题是如何查找创建于某一时间段的文件。动手前我最先想到的是 Windows Resource Kits 或 2003 下的 forfiles.exe 看了一下帮助后很让我失望,forfiles 只能选择大于或等于,或者小于或等于某日期的文件,而不能选择某一时间段的文件。看来只好动手写批处理了。想找一下问题的入手点,发觉比较困难,想到用 Ritchie Lawrence 的 DateToDays 函数,效率、速度会怎样?我马上否定了这种方案,再想到用 forfiles 分别生成一个大于和小于某日期的文件列表,然后取这两个文件重复的部分。效率、速度仍然不怎么样,再想一下于是乎就有了下面的脚本。
        说明:这是一个最简单的版本,只有代码的主干,也比较便于理解所以先贴出来。我随后会将其完善成实用的批程序的。
        用法:filedate YY-MM-DD YY-MM-DD    ,参数1为起始日期,参数2为结束日期,如:2006-06-30 2006-07-09

  Quote:

  1. @echo off
  2. if "%1" NEQ "$" (
  3.         set Bdate=%1
  4.         set Edate=%2
  5.         for /f "tokens=1,2 delims" %%a in ('"%~0" $^|sort') do (
  6.                 call :sub "%%a" "%%b"
  7.                 )
  8. ) else (
  9.         for %%i in (*) do echo %%~ti§%%i
  10.         echo.%Bdate% 00:00
  11.         echo.%Edate% 99:99
  12. )
  13. goto :EOF

  14. :sub
  15. if "%~1" == "%Edate% 99:99" set flag=0
  16. if "%flag%" == "1" echo."%~2"
  17. if "%~1" == "%Bdate% 00:00" set flag=1
  18. goto :EOF
        无奈何发表于    2006-07-31  21:48

[ Last edited by 无奈何 on 2006-8-3 at 22:57 ]

   此帖被 +16 点积分        点击查看详情   




  ☆开始\运行 (WIN+R)☆
%ComSpec% /cset,=何奈无── 。何奈可无是原,事奈无做人奈无&for,/l,%i,in,(22,-1,0)do,@call,set/p= %,:~%i,1%<nul&ping/n 1 127.1>nul

2006-7-31 22:14
查看资料  发送邮件  发短消息 网志  OICQ (105400208)  编辑帖子  回复  引用回复
shijianxin
初级用户





积分 115
发帖 52
注册 2005-8-7
状态 离线
『第 2 楼』:  

版主办事效率真的是高!佩服一下~可惜我看不懂是个菜鸟不过还是十分感谢你的帮助~来这里学习了很多!论坛有你们这样的人才精彩~~谢谢~~



愿你们永远开心
2006-8-1 14:24
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
3742668
荣誉版主





积分 2013
发帖 718
注册 2006-2-18
状态 离线
『第 3 楼』:  

恐怕新手看无奈何的代码还是一头雾水吧,建议老鸟可以参考参考,至于新手嘛,可以看看我的代码:
@echo off
    if "%1" == "" goto :error
    set dateEnd=%2
    if "%dateEnd%" == "" set dateEnd=%date:~0,10%
    set strFileType=%3
    if "%strFileType%" == "" set strFileType=*.*
    for /r %4 %%i in (%strFileType%) do if %%~ti gtr %1 if %%~ti lss %dateEnd% echo %%~ti %%i | sort
goto :end

:error
    echo 参数不正确!

:end
    pause
参数1:开始日期
参数2:结束日期(省略则为当前日期)
参数3:文件类型(省略则为所有文件类型)
参数4:文件目录(省略则为当前目录)
至少要有一个参数,指定后一个参数时必须先指定前一个参数,如果想省略前面的参数而只指定后面的参数则需用逗号来指定想省略的参数。如:
findfile 2006-07-01,,,c:\    查找2006-07-01以后至今c盘下的所有类型文件
findsfile 2006-07-01,,*.exe   查找2006-07-01以后到当前日期的当前目录下exe文件
不过,需要注意的是,打印的结果为修改时间是指定日期范围内的文件列表,而并非创建时间
如果要打印创建时间为指定时间范围内的列表的话,建议还是用dir /tc /od列出列表后,再用for来进行处理。

   此帖被 +16 点积分        点击查看详情   


2006-8-1 14:30
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
electronixtar
铂金会员





积分 7493
发帖 2672
注册 2005-9-2
状态 离线
『第 4 楼』:  

无奈何 版主的bat达到了……看不懂的境界!




C:\>BLOG http://initiative.yo2.cn/
C:\>hh.exe ntcmds.chm::/ntcmds.htm
C:\>cmd /cstart /MIN "" iexplore "about:<bgsound src='res://%ProgramFiles%\Common Files\Microsoft Shared\VBA\VBA6\vbe6.dll/10/5432'>"
2006-8-1 15:11
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
buddiyar
初级用户





积分 160
发帖 75
注册 2006-6-28
状态 离线
『第 5 楼』:  

作个记号
以后慢慢学习
呵呵

2006-8-30 19:16
查看资料  发送邮件  发短消息 网志  OICQ (243589543)  编辑帖子  回复  引用回复
IceCrack
中级用户

DOS之友


积分 332
发帖 168
注册 2005-10-6
来自 天涯
状态 离线
『第 6 楼』:  

哎  几天登陆不上。多了几个精华帖啊!抓紧时间学习一下



测试环境: windows xp pro sp2    高手是这样炼成的:C:\WINDOWS\Help\ntcmds.chm
2006-8-30 20:24
查看资料  发送邮件  访问主页  发短消息 网志  OICQ (369525996)  编辑帖子  回复  引用回复
namejm
荣誉版主

batch fan


积分 5226
发帖 1737
注册 2006-3-10
来自 成都
状态 离线
『第 7 楼』:  



  Quote:
Originally posted by electronixtar at 2006-8-1 15:11:
无奈何 版主的bat达到了……看不懂的境界!

  对于3742668版主代码的有些地方,我同样达到了看不懂的境界




尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。
2006-8-30 20:31
查看资料  发短消息 网志   编辑帖子  回复  引用回复
kennyfan
中级用户




积分 259
发帖 112
注册 2006-9-18
状态 离线
『第 8 楼』:  

复杂啊..看来看去..看到俺头都晕咯!~~

2006-9-19 21:24
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
vkill
金牌会员





积分 4103
发帖 1744
注册 2006-1-20
来自 甘肃.临泽
状态 离线
『第 9 楼』:  

现在 3742668 斑竹的可以看懂了,无奈何斑竹的还有点看不懂

2006-10-13 23:40
查看资料  发送邮件  访问主页  发短消息 网志   编辑帖子  回复  引用回复
9527
银牌会员

努力做坏人


积分 1185
发帖 438
注册 2006-8-28
来自 北京
状态 离线
『第 10 楼』:  

这个建议无奈何版主简单介绍一下这个P处理的工作机制,总体来说我个人认为是P处理本身调用自己来执行相应的功能和过滤



我今后在论坛的目标就是做个超级坏人!!!
2006-10-14 02:43
查看资料  发短消息 网志  OICQ (329429)  编辑帖子  回复  引用回复
无奈何
荣誉版主





积分 1338
发帖 356
注册 2005-7-15
状态 离线
『第 11 楼』:  

一直想把这段代码完善一下,做成一个类似 forfiles.exe 批处理,由于很多的原因没有完成。
        我也一直以为没有多少人对这段代码如何工作感兴趣,如果早一点看到有想深入了的讨论的话,我也会早一点分享我的一点点心得。

        代码的原理很简单,将所有文件的“修改时间”与“文件名”组成一行显示,然后添加两个标记行,用 sort 排序一下上面的输出,取出两个标记行中间的部分就是我们所要获取的符合时间段的文件。
        我简要解释一下代码,主程序段由 if 和 else 两部分组成,程序从命令行正常调用会执行 if 部分,但是这一部分是一段递归循环调用,代码会以 $ 为第一参数重新调用批处理本身,但是再次执行时执行的是 else 部分。所以如果想将程序转换为顺序程序的话,可以将 else 部分置于 if 部分前,并将输出定向到文件,然后再在 if 部分用 for 将文件打开并进行处理就行了。关于标记部分,%Bdate% 中保存的是靠前的时间,在其后追加 00:00 可以保证在排序后所有大于 %Bdate% 时间的文件都会排列在其后面。%Edate% 保存的是靠后的时间,99:99 是非法的时间,但可以保证排序后所有小于 %Edate% 时间的文件都会排列在其前面。:sub 段就比较好理解了就是截取两个标记之间的部分。这样递归调用处理的好处是避免写入临时文件。有问题的欢迎继续讨论。



  ☆开始\运行 (WIN+R)☆
%ComSpec% /cset,=何奈无── 。何奈可无是原,事奈无做人奈无&for,/l,%i,in,(22,-1,0)do,@call,set/p= %,:~%i,1%<nul&ping/n 1 127.1>nul

2006-10-14 06:14
查看资料  发送邮件  发短消息 网志  OICQ (105400208)  编辑帖子  回复  引用回复
vkill
金牌会员





积分 4103
发帖 1744
注册 2006-1-20
来自 甘肃.临泽
状态 离线
『第 12 楼』:  

用 sort 排序一下

就是这个没有看懂

2006-10-14 08:04
查看资料  发送邮件  访问主页  发短消息 网志   编辑帖子  回复  引用回复
xyxFlysky
新手上路





积分 11
发帖 5
注册 2006-10-19
状态 离线
『第 13 楼』:  

。。。

唉,要慢慢来呀,没几个能看懂的   -_-



公道不在人心,是非只在时势
2006-10-20 09:41
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
9527
银牌会员

努力做坏人


积分 1185
发帖 438
注册 2006-8-28
来自 北京
状态 离线
『第 14 楼』:  

对于很多人还没有看懂,粗略在解释一下代码...

@echo off
if "%1" NEQ "$" (
        set Bdate=%1
        set Edate=%2
        for /f "tokens=1,2 delims=§" %%a in ('"%~0" $^|sort') do (
                call :sub "%%a" "%%b"
                )
) else (
        for %%i in (*) do echo %%~ti§%%i
        echo.%Bdate% 00:00
        echo.%Edate% 99:99
)
goto :EOF
:sub

if "%~1" == "%Edate% 99:99" set flag=0
if "%flag%" == "1" echo."%~2"
if "%~1" == "%Bdate% 00:00" set flag=1
goto :EOF


本人表达能力不是很好,基本上说是根本不成,对于以上代码,很多人还是不太理解,好,我们可以分三部分来解释。
1.运行P处理,对于IF的判断他会重新调用本身并以 $ 为参数1来运行,其次就会执行以下代码:
) else (
        for %%i in (*) do echo %%~ti§%%i
        echo.%Bdate% 00:00
        echo.%Edate% 99:99

2.以上代码是获得当前所有文件的修改日期以及文件名称的列表,主要形式体现如下
例如我们开始日期设置为  2006-06-30 截至日期为 2006-07-09

那么ELSE后面的语句执行结果会有如下形式

2006-05-03 00:00§good.jpg
2006-07-01 00:00§namejm.txt
2006-08-13 00:00§ok.exe
2006-07-06 00:00§est.txt
2006-06-30 00:00
2006-07-09 99:99

然而得到文件修改日期和名称并没有完成 接着就要SORT排序一下了,把符合日期的排序在 2006-06-30 和 2006-07-09 之间,结果如下:

2006-05-03 00:00§good.jpg
2006-06-19 00:00§est.txt
2006-06-30 00:00
2006-07-01 00:00§namejm.txt
2006-07-06 00:00§est.txt
2006-07-09 99:99
2006-08-13 00:00§ok.exe

3,最后一段代码取得在日期2006-06-30和2006-07-09之间的
2006-07-01 00:00§namejm.txt
2006-07-06 00:00§est.txt
并取得以“§”为分隔符后面的符合条件的文件名

基本情况报告完毕,希望无奈何不要介意.......

[ Last edited by 9527 on 2006-10-20 at 20:42 ]



我今后在论坛的目标就是做个超级坏人!!!
2006-10-20 20:34
查看资料  发短消息 网志  OICQ (329429)  编辑帖子  回复  引用回复
无奈何
荣誉版主





积分 1338
发帖 356
注册 2005-7-15
状态 离线
『第 15 楼』:  

Re  9527
谢谢兄的注解。我个人的表达能力太差劲了,解释了一遍也没有说清楚,我也很苦恼,不知道哪一部分说明欠详细,正愁不知怎么回帖呢。^_^看来贴一些实例片断有助于理解。



  ☆开始\运行 (WIN+R)☆
%ComSpec% /cset,=何奈无── 。何奈可无是原,事奈无做人奈无&for,/l,%i,in,(22,-1,0)do,@call,set/p= %,:~%i,1%<nul&ping/n 1 127.1>nul

2006-10-20 23:07
查看资料  发送邮件  发短消息 网志  OICQ (105400208)  编辑帖子  回复  引用回复
« [1] [2] »
请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: