Board logo

标题: [文本处理] 批处理 如何删除以系统日期创建的前一周的文件夹 [打印本页]

作者: 菜鸟一个    时间: 2012-4-15 09:08     标题: 批处理 如何删除以系统日期创建的前一周的文件夹

知道这里有很多批处理告诉  来问个菜鸟问题

大概情况是:
在一个文件夹下面,有若干个以年月日命名的文件夹:命名方式 2012-1-1  2012-1-2 2012-4-31 那么多文件夹
这些文件夹里面 可能还有 .txt的文本文件

要实现的效果:
每次运行批处理,删除指定时间的前一周文件夹   

不知道我说的是否清楚..求高手指点..
作者: fatcat    时间: 2012-4-15 10:42

本帖最后由 fatcat 于 2012-4-15 11:52 编辑

回复 1# 菜鸟一个
下面是 有问题 的啊, 请楼主看 plp626 的代码, 或者看我 8 楼的代码吧
  1. @echo off & setlocal enabledelayedexpansion
  2. echo 请输入指定日期:
  3. for %%a in (y m d) do set /p "%%a=%%a: " & set /a "%%a=1000!%%a! %% 10000"
  4. set /a "d-=7, m+=d-1>>32,y+=m-1>>32,m+=^!m*12,d+=(d-1>>32)&(31-(^!(m-4)|^!(m-6)|^!(m-9)|^!(m-11))-^!(m-2)*(3-(^!(y%%4)&^!^!(y%%100)|^!(y%%400))))"
  5. 2>nul md "!y!-!m!-!d!"
  6. for /f %%d in ('dir /ad /o-d /tc /b') do (
  7.   if "!weekago!"=="1" del /f /s /q "%%~d" & rd /q "%%~d"
  8.   if "%%~d"=="!y!-!m!-!d!" set "weekago=1"
  9. )
  10. rd /q "!y!-!m!-!d!"
复制代码

作者: neorobin    时间: 2012-4-15 10:48

回复 1# 菜鸟一个

    将 2 楼代码存为 批处理文件 放在 2012-1-1  2012-1-2 2012-4-31 这些文件夹的 父目录.

代码中,
  1. d-=7
复制代码
7 可以改为 [1,28] 内的任意一个, 就变成了相应多少天前的.
作者: plp626    时间: 2012-4-15 10:52

本帖最后由 plp626 于 2012-4-15 11:06 编辑
  1. @echo off&setlocal enabledelayedexpansion
  2. :: 删除该脚本所在文件夹下 系统创建的
  3. ::            指定日期前7天(不含7天)的文件夹(非隐藏属性,不含子目录)
  4. set 指定日期=2012-4-15
  5. set 之前=-7
  6. call:date2i  "%指定日期%" ans
  7. set/a ans+=之前
  8. for /f "skip=2 tokens=1-3*" %%a in ('dir/a-h/tc/4^|find "<DIR>"')do (
  9.      call:date2i "%%a" num
  10.      rem 要删除时,把下面“ECHO”删掉即可
  11.      if !num! lss !ans! ECHO rd/s "%%~d"
  12. )
  13. pause
  14. exit
  15. :date2i <yyyy-mm-dd> <ret>
  16. setlocal&set tp=%~1
  17. for /f "tokens=1-3delims=-" %%a in ("%tp:-0=-%")do set/a y=%%a,m=%%b,d=%%c
  18. set/a "m=(m+9)%%12,y-=m/10+1900,i=365*y+y/4+(m*153+2)/5+d-1"
  19. endlocal&set %2=%i%&goto:eof
复制代码

作者: fatcat    时间: 2012-4-15 11:00

2 楼的代码有问题, 要先把 日期调整到 相应天数之前, 再创建那个 标记文件夹
作者: fatcat    时间: 2012-4-15 11:22

回复 4# plp626

如此情况,
  1. set /a "i=(((y<<4)+m)<<5)+d"
复制代码
, 用来比较日期大小就可以了, 同样方式先算出 一周前相应日期的序号, 这种序号计算不是完全连续性的, 但对比较大小可以用了
作者: plp626    时间: 2012-4-15 11:36

本帖最后由 plp626 于 2012-4-15 11:40 编辑

为了通用吧;
你的代码让新手很不好看懂;
  1. set /a "i=(((y<<4)+m)<<5)+d"
  2. 作用同下面任意一句:
  3. set/a i=(y*16+m)*32+d
  4. set/a i=512*y+32*m+d
复制代码
你的意思是否如下:
  1. i=y*10000+m*100+d
复制代码

作者: fatcat    时间: 2012-4-15 11:48

回复 7# plp626

是的, 确实如此, 好处是形式很简单了, 不好的是 适应的天数 是 很 有限 的, 下面的代码 d-=7 中, 7 可以在 [1,28] 内改动,
  1. @echo off & setlocal enabledelayedexpansion
  2. echo 请输入指定日期:
  3. for %%a in (y m d) do set /p "%%a=%%a: " & set /a "%%a=1000!%%a! %% 10000"
  4. set /a "d-=7, m+=d-1>>32,y+=m-1>>32,m+=^!m*12,d+=(d-1>>32)&(31-(^!(m-4)|^!(m-6)|^!(m-9)|^!(m-11))-^!(m-2)*(3-(^!(y%%4)&^!^!(y%%100)|^!(y%%400)))), i=(((y<<4)+m)<<5)+d"
  5. for /f "tokens=1-3 delims=-" %%a in ('dir /ad /o-d /tc /b^|findstr "^[0-9]*\-[0-9][0-9]*\-[0-9][0-9]*"') do (
  6.   set /a "daysAgo=(((%%a<<4)+%%b)<<5)+%%c-i"
  7.   if !daysAgo! leq 0 del /f /s /q "%%a-%%b-%%c" & rd /q "%%a-%%b-%%c"
  8. )
复制代码

作者: xiaopo    时间: 2012-4-15 12:52

为了通用吧;
你的代码让新手很不好看懂;你的意思是否如下:
plp626 发表于 2012-4-15 11:36



    9494,你写那种逻辑移位的代码让我等新手情何以堪,左移1位表示乘以2,4的话就是16了,5的话就是32。右移相当于除了。还是plp大神照顾新手啊。
作者: fatcat    时间: 2012-4-15 13:05

本帖最后由 fatcat 于 2012-4-15 13:10 编辑

回复 9# xiaopo

嗯, 位运算不是很难理解, 熟练运用的话, 大有好处的, 用于 两个日期 比较大小 的话, 将一个 三元 的 日期 转化为 一元 的整数用下面的代码很实用的:
  1. y<<9|m<<5|d
复制代码

作者: 菜鸟一个    时间: 2012-4-16 09:52

回复 8# fatcat


    能稍微做点解释吗? 还是有点看不明白...
作者: 菜鸟一个    时间: 2012-4-16 09:52

回复 4# plp626


    能解释下大致意思吗? 谢谢
作者: fatcat    时间: 2012-4-16 10:53

回复 11# 菜鸟一个
for %%a in (y m d) do set /p "%%a=%%a: " & set /a "%%a=1000!%%a! %% 10000"
  获取你指定的 年,月,日, 1000!%%a! %% 10000 是为了适应你把数字前面打了前缀的 0, 比如 9 月打成 09, 也一样可以让 m 得到 9 的值.

set /a "d-=7, m+=d-1>>32,y+=m-1>>32,m+=^!m*12,d+=(d-1>>32)&(31-(^!(m-4)|^!(m-6)|^!(m-9)|^!(m-11))-^!(m-2)*(3-(^!(y%%4)&^!^!(y%%100)|^!(y%%400)))), i=(((y<<4)+m)<<5)+d"
            先计算 7 天前的日期, 再把那个日期转化成一个整数:
  d-=7,       日数减 7;
  m+=d-1>>32, 如果日数小于 1 了, 月数加 -1;
  y+=m-1>>32, 如果月数小于 1 了, 年数加 -1;
  m+=^!m*12,  如果月数等于 0 了, 月数加 12;
  d+=(d-1>>32)&(31-(^!(m-4)|^!(m-6)|^!(m-9)|^!(m-11))-^!(m-2)*(3-(^!(y%%4)&^!^!(y%%100)|^!(y%%400)))),
              如果日数小于 1 了, 按月数的情况加上 31(大月) 或者 (31-1)(小月) 或者 (31-3)(平年 2 月) 或者 (31-(3-1))(闰年 2 月);
  i=(((y<<4)+m)<<5)+d,
              相当于 (y<<9)+(m<<5)+d, 也相当于 y*2^9+m*2^5+d, 将 三元 的日期转化成一个整数, 便于比较大小.
            
dir /ad /o-d /tc /b,
            以空格式, 以创建时间逆序(后创建的在前)显示当前目录下的子目录;
findstr "^[0-9]*\-[0-9][0-9]*\-[0-9][0-9]*",
            找出 形如 "若干数字-至少1到2个数字-至少1到2个数字" 这样的样式: 例如: 2012-4-16;

for /f "tokens=1-3 delims=-" %%a in ...
            将样式匹配 "2012-4-16" 类似形式的目录名解析成 3 部分, y -> %%a, m -> %%b, d -> %%c
daysAgo=(((%%a<<4)+%%b)<<5)+%%c-i,
            前面 i 已经成为 7 天前日期对应的整数, 这里, 将每一个子目录的名称对应的 y/m/d 以同样方式转化为一个整数.
            如果这个整数小于或等于 i, 就表明这个子目录的创建日期是指定日期 7 天或更多天之前, 所以可以删除.
作者: gawk    时间: 2012-4-16 11:57

回复 11# 菜鸟一个


http://www.bathome.net/thread-1844-1-1.html




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