Board logo

标题: [文件操作] [已解决]批处理按最近修改时间查找N天内的目录并生成列表? [打印本页]

作者: sonorous    时间: 2010-5-28 16:13     标题: [已解决]批处理按最近修改时间查找N天内的目录并生成列表?

按最近修改时间查找出N天以内的目录并生成列表,请问代码如何写?

用forfiles只能查找N天以前的,不是N天以内的,而且forfiles好像不能只显示目录 这个需求在unix/linux里就是一条find命令,在dos下怎么实现呢?linux系统里如下:

find / -type d -mtime -XXX -print > /tmp/list.txt

[ 本帖最后由 sonorous 于 2010-5-28 21:41 编辑 ]
作者: hanyeguxing    时间: 2010-5-28 16:55

DOS系统下,还是 xp 系统的命令提示符下?
作者: CUer    时间: 2010-5-28 16:59

去下载一个 GNU for windows 版本的find.exe不就行了?
作者: sonorous    时间: 2010-5-28 17:05

是win2003的系统,不让装第三方软件,所以只能用系统批处理来解决
作者: hanyeguxing    时间: 2010-5-28 17:40

有效查询范围,上月1号到今天:
  1. @echo off&setlocal enabledelayedexpansion
  2. ::设置几天内
  3. set n=10
  4. ::设置路径
  5. set "p="D:\rec""
  6. for /f "tokens=1-3 delims=-:/ " %%a in ("%date%") do (
  7. set Y=%%a&set M=%%b&set D=%%c
  8. if "!M:~0,1!"=="0" set M=!M:~1!
  9. if "!D:~0,1!"=="0" set D=!D:~1!
  10. )
  11. set/a D-=n
  12. if %D% leq 0 (
  13. set/a M-=1
  14. if !M!==0 set/a Y-=1,M=12
  15. set/a "T=^!(M-2)","R=(^!(Y%%4)&^!^!(Y%%100))|^!(Y%%400)","C=^!(M-4)|^!(M-6)|^!(M-9)|^!(M-11)","D=T*(28+R)+C*30+(^!T&^!C)*31+D"
  16. )
  17. set M=0%M%&set D=0%D%&set n=%Y%!M:~-2!!D:~-2!
  18. (for /f "delims=" %%a in ('dir /s/b/ad %p%') do (
  19. set t=%%~ta&set t=!t:-=!
  20. if !t:~0^,8! gtr %n% echo.%%a
  21. ))>c:\输出_%n%.txt
复制代码

[ 本帖最后由 hanyeguxing 于 2010-5-28 20:37 编辑 ]
作者: sonorous    时间: 2010-5-28 19:29

LS的,真是感谢,太强了,我试了一下,基本上实现了我要的功能,但是还有一点点小问题,能否把上层目录去掉,不然就重复了,例如:
d:\test
d:\test\1
d:\test\2
.......
生成的列表中只要d:\test\1和d:\test\2就可以了,d:\test不需要了,只要有了子目录就可以了,能否再改一下代码
作者: sonorous    时间: 2010-5-28 19:40

原帖由 hanyeguxing 于 2010-5-28 17:40 发表
有效查询范围,上月1号到今天:@echo off&setlocal enabledelayedexpansion
::设置几天内
set n=10
::设置路径
set "p="D:\rec""
for /f "tokens=1-3 delims=-:/ " %%a in ("%date%") do (
set Y=%%a&set M=%% ...


刚才试了一下,把set n=3,发现昨天的目录没有被包含进去,而我在cygwin下用find,是有的,

另外,我随便试了一下把n设成70,输出的文件名中是20100400,也就是%n%的值为20100400,是日期算错了吗?而把n设为3的时候,%n%是20100525,是对的,请问%n%是不是N天前的具体日期啊?可能是我理解错了

[ 本帖最后由 sonorous 于 2010-5-28 19:55 编辑 ]
作者: sonorous    时间: 2010-5-28 19:49

关健就是换算日期的那段看不懂,还请各位大师多指点啦!

刚又试了一下,日期不能早于当月,比如今天是28号,如果set n=28,就不行了,n=27,可以正常显示20100501

[ 本帖最后由 sonorous 于 2010-5-28 19:58 编辑 ]
作者: hanyeguxing    时间: 2010-5-28 19:58

5楼代码有运行前提:有效查询范围,上月1号到今天,以今天为5月28为例,n的范围为(30+28)即58天。
ps:推荐楼主重新复制5楼的代码,因为刚才把 set/a 表达式中一个字母打错了。

[ 本帖最后由 hanyeguxing 于 2010-5-28 20:02 编辑 ]
作者: sonorous    时间: 2010-5-28 20:02

前面有点乱,我来简单总结一下目前发现的几个问题:
1.例如我把n=3,发现昨天(5.27)的目录是没有被包含进去的,而我在cygwin下用find,是正常的

2.日期不能早于当月,比如今天是28号,如果set n=27,可以正常显示20100501,如果n=28,会显示20100460,n=29,则20100459,以此类推(重新复制代码后,问题已经解决,但是还是有范围上的限制,即只能从上个月1号到今天)

3.把上层目录去掉,例如:
d:\test
d:\test\1
d:\test\2
能否实现生成的列表中只要d:\test\1和d:\test\2,不需要d:\test

4.能否把日期范围扩大到100天,或者没有范围的定义,n可以设为任意数,可以做到吗?

[ 本帖最后由 sonorous 于 2010-5-28 20:13 编辑 ]
作者: hanyeguxing    时间: 2010-5-28 20:12

因为临时写的,算法没有优化:
  1. @echo off&setlocal enabledelayedexpansion
  2. ::设置几天内
  3. set n=150
  4. ::设置路径
  5. set "p="D:\rec""
  6. for /f "tokens=1-3 delims=-:/ " %%a in ("%date%") do (
  7. set Y=%%a&set M=%%b&set D=%%c
  8. if "!M:~0,1!"=="0" set M=!M:~1!
  9. if "!D:~0,1!"=="0" set D=!D:~1!
  10. )
  11. set/a D-=n
  12. if %D% leq 0 goto:han
  13. :ye
  14. set M=0%M%&set D=0%D%&set n=%Y%!M:~-2!!D:~-2!
  15. (for /f "delims=" %%a in ('dir /s/b/ad %p%') do (
  16. set t=%%~ta&set t=!t:-=!
  17. if !t:~0^,8! gtr %n% echo.%%a
  18. ))>c:\输出_%n%.txt
  19. exit
  20. :han
  21. set/a M-=1
  22. if !M!==0 set/a Y-=1,M=12
  23. set/a "T=^!(M-2)","R=(^!(Y%%4)&^!^!(Y%%100))|^!(Y%%400)","C=^!(M-4)|^!(M-6)|^!(M-9)|^!(M-11)","D=T*(28+R)+C*30+(^!T&^!C)*31+D"
  24. if %D% leq 0 (goto:han) else goto:ye
复制代码
原帖由 sonorous 于 2010-5-28 19:29 发表

LS的,真是感谢,太强了,我试了一下,基本上实现了我要的功能,但是还有一点点小问题,能否把上层目录去掉,不然就重复了,例如:
d:\test
d:\test\1
d:\test\2
.......
生成的列表中只要d:\test\1和d:\test\2就可以了,d:\test不需要了,只要有了子目录就可以了,能否再改一下代码
这个问题需要单独开新贴,因为他和时间没有关系

[ 本帖最后由 hanyeguxing 于 2010-5-28 20:37 编辑 ]
作者: sonorous    时间: 2010-5-28 20:29

1.例如我把n=3,发现昨天(5.27)的目录是没有被包含进去的,而我在cygwin下用find,是正常的(这个问题查到原因了,是目录带空格引起的,不带空格的目录没问题,带空格的目录都不行,还望大师能解决一下)

2.日期不能早于当月,比如今天是28号,如果set n=27,可以正常显示20100501,如果n=28,会显示20100460,n=29,则20100459,以此类推(问题已经解决,范围上好像也没有限制了,多谢!)


[ 本帖最后由 sonorous 于 2010-5-28 20:34 编辑 ]
作者: hanyeguxing    时间: 2010-5-28 20:38

  1. @echo off&setlocal enabledelayedexpansion
  2. ::设置几天内
  3. set xing=150
  4. ::设置路径
  5. set "p=D:\rec"
  6. call:han %xing%
  7. (for /f "delims=" %%a in ('dir /s/b/ad "%p%"') do set t=%%~ta&set t=!t:-=!&if !t:~0^,8! gtr %xing% echo.%%a))>c:\输出_%n%.txt
  8. pause&exit
  9. :han:几天前的计算
  10. for /f "tokens=1-3 delims=-:/ " %%a in ("%date%") do (
  11. set Y=%%a&set M=%%b&set D=%%c
  12. if "!M:~0,1!"=="0" set M=!M:~1!
  13. if "!D:~0,1!"=="0" set D=!D:~1!)
  14. set/a D-=%1
  15. if %D% gtr 0 goto:gu
  16. :ye
  17. set/a M-=1
  18. if !M!==0 set/a Y-=1,M=12
  19. set/a "T=^!(M-2)","R=(^!(Y%%4)&^!^!(Y%%100))|^!(Y%%400)","C=^!(M-4)|^!(M-6)|^!(M-9)|^!(M-11)","D=T*(28+R)+C*30+(^!T&^!C)*31+D"
  20. if %D% leq 0 goto:ye
  21. :gu
  22. set M=0%M%&set D=0%D%&set xing=%Y%!M:~-2!!D:~-2!
复制代码

[ 本帖最后由 hanyeguxing 于 2010-5-29 00:02 编辑 ]
作者: sonorous    时间: 2010-5-28 20:45

原帖由 hanyeguxing 于 2010-5-28 20:38 发表
楼主重新运行测试下。。。


代码有更新过了?我发贴前试过的,带空格的不行呢

刚才又测试了一次,只要带空格的目录就不行,包括下面不带空格的子目录也筛选不出来

[ 本帖最后由 sonorous 于 2010-5-28 20:49 编辑 ]
作者: sonorous    时间: 2010-5-28 21:15

set "p=D:\rec",引号必须保留。


试过了,不行

原来是set "p="D:\rec""

改成set "p=D:\rec",结果是一样的
作者: hanyeguxing    时间: 2010-5-28 22:42

下回记得多刷新几次。。。
作者: sonorous    时间: 2010-5-29 11:07

多谢LS的,现在还剩个问题,就是提取最深目录,但又不能装sed
作者: hanyeguxing    时间: 2010-5-29 14:25

对输出结果使用 findstr 进行再处理:
  1. (for /F "delims=" %%a in (1.txt) do (findstr /i /b /l /c:"%%a\\" 1.txt>nul||echo.%%a))>2.txt
复制代码
也就是:
  1. @echo off&setlocal enabledelayedexpansion
  2. ::设置几天内
  3. set xing=150
  4. ::设置路径
  5. set "p=D:\rec"
  6. call:han %xing%
  7. (for /f "delims=" %%a in ('dir /s/b/ad "%p%"') do set t=%%~ta&set t=!t:-=!&if !t:~0^,8! gtr %xing% echo.%%a))>$temp$
  8. (for /F "delims=" %%a in ($temp$) do (findstr /i /b /l /c:"%%a\\" $temp$>nul||echo.%%a))>结果.txt
  9. del $temp$
  10. pause&exit
  11. :han:几天前的计算
  12. for /f "tokens=1-3 delims=-:/ " %%a in ("%date%") do (
  13. set Y=%%a&set M=%%b&set D=%%c
  14. if "!M:~0,1!"=="0" set M=!M:~1!
  15. if "!D:~0,1!"=="0" set D=!D:~1!)
  16. set/a D-=%1
  17. if %D% gtr 0 goto:gu
  18. :ye
  19. set/a M-=1
  20. if !M!==0 set/a Y-=1,M=12
  21. set/a "T=^!(M-2)","R=(^!(Y%%4)&^!^!(Y%%100))|^!(Y%%400)","C=^!(M-4)|^!(M-6)|^!(M-9)|^!(M-11)","D=T*(28+R)+C*30+(^!T&^!C)*31+D"
  22. if %D% leq 0 goto:ye
  23. :gu
  24. set M=0%M%&set D=0%D%&set xing=%Y%!M:~-2!!D:~-2!
复制代码

[ 本帖最后由 hanyeguxing 于 2010-5-29 17:00 编辑 ]




欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2