Board logo

标题: 删除D盘下文件夹名为数字(0-999999)下的影音文件 [打印本页]

作者: tide2046     时间: 2006-9-26 22:52    标题: 删除D盘下文件夹名为数字(0-999999)下的影音文件

想写个批处理,要删除多个文件夹(文件夹名是0-99999,中间并不是连续的,有缺省的可能)下所有的影音文件。请高手解答,谢谢了
作者: NaturalJ0     时间: 2006-9-26 23:43
为什么不直接把上一级目录删了
作者: tide2046     时间: 2006-9-26 23:54
目录中还有别的文件
象网页文件等等的。。。
要求只是删除影音文件

目前删除影音文件已经解决

但是不知道如何判断文件夹。。。

跪求高手解答
作者: pengfei     时间: 2006-9-27 00:05
最简单的方法:
del /s /a /q *.avi

判断文件夹是否存在, 再执行删除该文件夹下影音文件的代码:
@echo off
for /l %%i in (0,1,9999) do (
    if exist %%i (
        del /s /a /q %%i\*.avi
    )
)
pause
作者: tide2046     时间: 2006-9-27 01:30
这个有点问题,如果文件夹名为0起头,比如0123 ,这样的文件夹里的文件就删除不掉了
作者: pengfei     时间: 2006-9-27 02:01
你把文件夹名的规律介绍一下!
作者: NaturalJ0     时间: 2006-9-27 02:36
setlocal ENABLEDELAYEDEXPANSION
for /f %%i in ('dir/ad/b') do (
        set /a varnum=%%i
        if not !varnum!==0 (
                del /q %%i\*.avi
                del /q %%i\*.wmv
                del /q %%i\*.mpg
                del /q %%i\*.mpeg
                del /q %%i\*.rm
                del /q %%i\*.rmvb
                del /q %%i\*.mov
                del /q %%i\*.divx
rem 要是还不够自己再加些
        )
)
0 00 000 0000 00000 000000 ...这些目录没处理,不过大概你也没有这些目录吧,猜的 ^_^

[ Last edited by NaturalJ0 on 2006-9-27 at 02:45 ]
作者: tide2046     时间: 2006-9-27 02:36
就是只包含数字    没有任何其他字符  也没有空格   

数字的组合方式不限   可以是  0  也可以是654   也可以是  0654   等等   0的位置不限
作者: namejm     时间: 2006-9-28 04:45
  试试下面的代码,可能会有用(代码为演示性质,如果觉得可靠,把后一个 echo %%i 改为 del /q %%i  即可):
@echo off
for /f %%i in ('dir /ad /b') do (
    echo %%i| findstr "^[0-9]*$">nul && echo %%i
)
pause

作者: tide2046     时间: 2006-9-28 05:34
昨天有人给我一个程序段,和这个差不多

但是,有点问题

这个会删除某个盘符下所有的数字命名的文件夹里的影音文件

现在上司给的指示是:只能是父目录为数字的文件夹里的影音文件和其子目录名同样为数字的文件夹里的影音文件才可以删

即:比如 D:/music/123/*.rm   这样的不能删

而:D:3213/321/*.rm   这样的需要删除


期待高手赐教
作者: pengfei     时间: 2006-9-28 05:36


  Quote:
Originally posted by namejm at 2006-9-28 04:45:
  试试下面的代码,可能会有用(代码为演示性质,如果觉得可靠,把后一个 echo %%i 改为 del /q %%i  即可):
[code]
@echo off
for /f %%i in ('dir /ad /b') do (
...

兄一个正则表达式用得妙, 楼主的文件夹没有规律可循(说到规律就只有先去零后比对,不可取). 而正则表达式匹配以0-9命名的文件夹, 成功解决了这个难题.
作者: tide2046     时间: 2006-9-28 05:58
pengfei老兄,你上面给的程序能解决我这个新的要求

  Quote:
Originally posted by tide2046 at 2006-9-28 05:34:
昨天有人给我一个程序段,和这个差不多

但是,有点问题

这个会删除某个盘符下所有的数字命名的文件夹里的影音文件

现在上司给的指示是: ...

但是执行效率太低啊,尤其是数据大的时候
作者: namejm     时间: 2006-9-28 07:00
  经过楼主的测试,下面的代码可以实现『第 10 楼』的意图,速度还不错(暂时没有考虑路径带空格的情况):
@echo off
setlocal enabledelayedexpansion
for /f %%i in ('dir /ad /b /s') do (
    set route=%%i
    set route_=!route:%cd%=!
    set route_=!route_:\=!
    echo !route_!|findstr "^[0-9]*$">nul && (
        for %%j in (avi wmv mpg mpeg rm rmvb mov divx mp3 wav wma swf) do (
            if exist %%i\*.%%j del /a /f %%i\*.%%j
        )
    )
)
pause
  居然把"路径"这个词语的英文写成 root,修改一下下,汗~~~

  和 pengfei 讨论了一下,发现可以不用 pushd 和 popd,但是就不能把 del 语句换成 echo 语句来测试了。删除有风险,删除之前请先做好备份。

[ Last edited by namejm on 2006-9-28 at 11:55 ]
作者: pengfei     时间: 2006-9-28 07:01

at 2006-9-28 05:34:

这个会删除某个盘符下所有的数字命名的文件夹里的影音文件

现在上司给的指示是:只能是父目录为数字的文件夹里的影音文件和其子目录名同样为数字的文件夹里的影音文件才可以删

即:比如 D:/music/123/*.rm   这样的不能删

而:D:3213/321/*.rm   这样的需要删除
终于解决群主说的这个难题了, 但是速度依然很慢! 请先去掉删除测试...   刚刚发完贴发现namijm兄已经写好了, 并且思路也差不多!

@echo off
::__删除当前目录下以纯数字命名的所有子目录中的指定文件.
::__测试前请将del /a /q "!route!\*.%%c" 1>nul 2>nul这一句去掉, 如果可行再执行删除!
set root=%cd%
setlocal enabledelayedexpansion
for /f "tokens=*" %%i in ('dir /ad /b /s') do (
    set route=%%i
    set "route_=!route:%root%=!"
    set "route_=!route_:\=!"
    echo !route_!|findstr "^[0-9]*$" 1>nul 2>nul && call :go
)
echo 代码执行完毕^^!
pause


::__更多的影音类型请在下面FOR语句中按当前格式添加.
:go
for %%c in (avi mp3 rm rmvb mp4 wmv wav swf) do (
    if exist "!route!\*.%%c" (
      echo 待操作的文件夹__!route!
      del /a /q "!route!\*.%%c" 1>nul 2>nul
    )
)
goto :eof

[ Last edited by pengfei on 2006-9-28 at 20:35 ]
作者: pengfei     时间: 2006-9-28 07:02
在14楼代码的基础上修改, 完全抛开了13楼与14楼中的正则表达式用法. 因此速度得到大幅度提升,  另外一个优点是可以匹配非纯数字目录(慎用!).  经过测试执行相同的任务, 14楼需要大约28秒, 而本段代码大约只需要9秒.

经过反复测试, 完全正常, 可以在任意目录下执行, 不存在目录名中有空格不能执行的问题. 为了安全起见请先去掉del /a /q "!route!\*.%%c" 1>nul 2>nul这一句进行测试~~~!
@echo off
::__快速删除当前目录下以纯数字命名的所有子目录中的指定文件.
::__测试前请将del /a /q "!route!\*.%%c" 1>nul 2>nul这一句去掉, 如果可行再执行删除!
set root=%cd%
setlocal enabledelayedexpansion
for /f "tokens=*" %%i in ('dir /ad /b /s') do (
    set route=%%i
    set route_=!route!:
    set "route_=!route_:%root%=!"
    set "route_=!route_:\=!"
    call :go
)
echo 代码执行完毕^^!
pause

:go
set num=!route_:~0,1!
if not "!num!"==":" (
    set term=
    for %%a in (0 1 2 3 4 5 6 7 8 9) do (
        if "!num!"=="%%a" (
            set route_=!route_:~1!
            set term=
            goto go
        )
    )
    if "!term!"=="" goto :eof
    goto go
)
::__更多的影音类型请在下面FOR语句中按当前格式添加.
for %%c in (avi mp3 rm rmvb mp4 wmv wav swf) do (
    if exist "!route!\*.%%c" (
        echo 待操作的文件夹__!route!
        del /a /q "!route!\*.%%c" 1>nul 2>nul
    )
)
goto :eof
给楼主提个小建议, 把del /a /q "!route!\*.%%c" 1>nul 2>nul 改成 echo 待操作的文件夹__!route!>>file.txt

这样打开file.txt, 需要执行删除的文件夹就一目了然. 请在确认安全后再改成del.

[ Last edited by pengfei on 2006-9-28 at 23:05 ]
作者: tide2046     时间: 2006-9-28 21:41
那我想在删除前把这些文件备份,包括目录结构,和里面所有的文件

也就是说

比如 删除D:/music/123/*.rm   就把123文件夹里所有的文件  和 目录结构一起备份

如果能把music文件夹整个备份当然更好


请兄赐教啊
作者: NaturalJ0     时间: 2006-9-28 21:48
备份就用鼠标吧
作者: pengfei     时间: 2006-9-28 22:52


  Quote:
Originally posted by tide2046 at 2006-9-28 21:41:
那我想在删除前把这些文件备份,包括目录结构,和里面所有的文件

也就是说

比如 删除D:/music/123/*.rm   就把123文件夹里所有的文件  和 目录结构 ...

楼上说的对, 你备份就在Windows 下吧, 用cmd会很麻烦,  昨天整了一个晚上, 挺累的, 休息去了.
作者: namejm     时间: 2006-9-28 22:53


  Quote:
Originally posted by pengfei at 2006-9-28 07:02:
在14楼代码的基础上修改, 完全抛开了13楼与14楼中的正则表达式用法. 因此速度得到大幅度提升,  另外一个优点是可以匹配非纯数字目录(慎用!).  经过浠...

  通过截取字符来判断的方法确实不错,比 echo|findstr 效率高多了,赞一个先。

  下一步可以考虑路径带空格的问题,呵呵。
作者: pengfei     时间: 2006-9-28 23:03


  Quote:
Originally posted by namejm at 2006-9-28 22:53:

  通过截取字符来判断的方法确实不错,比 echo|findstr 效率高多了,赞一个先。

  下一步可以考虑路径带空格的问题,呵呵。

呵呵~ 我写批处理的很多思路来自C语言中的算法...

15, 16楼的代码已经可以处理带空格路径的文件夹了.

[ Last edited by pengfei on 2006-9-28 at 23:06 ]
作者: 3742668     时间: 2006-9-29 01:49
Part 1:

  Quote:

@echo off
    set strOldDir=%cd%
    set strRegExp=".*\\[0-9]*\\[0-9]*$"
rem set strRegExp=".*\\[0-9]*$"
    set strFileExtension=*.wmv *.rm *.rmvb *.avi *.mp3 *.wma *.wav
    for /f "delims=" %%i in ('dir /ad /s /b ^| findstr /rc:%strRegExp%') do cd "%%i" && echo %%i && dir /b %strFileExtension%
rem for /f "delims=" %%i in ('dir /ad /s /b ^| findstr /rc:%strRegExp%') do cd "%%i" && del %strFileExtension%
    cd %strOldDir%
pause
注意事项:
1.此脚本为演示效果,若要删除影音文件,可以把第二个for语句前面的rem移到第一个for语句之前。
2.若要添加备份目录功能,可以直接用xcopy在for语句里面自行添加。
3.默认目录格式若: x:\xxx\数字\数字\影音文件(如要包括子目录可在for语句中的del/dir命令后加上/s参数),如果移动第四行前面的rem到第三行行首,则默认目录格式若: x:\xxx\数字\影音文件
4.以上代码均未测试。

Part 2:

  Quote:
关于回贴中提到的不用findstr的方法的两点想法:
1.关于获得最后两个目录
for ..... do (
    set "strDir="%%i""
    set "strDir=!strDir:\=" "!"
    for %%? in (!strDir!) do strTmp=%%? !strTmp!
    call :dosomething !strTmp!
)
....

:dosomething
    rem 在这个标号段中只需要对%1和%2做判断就可以了。
    rem %1对应最低层子目录,%2为%1的父目录。
goto :eof
2.关于判断目录是否全为数字:
:IsNumber
    set "strNum=%~1%~2"
    for /l %%i in (0,1,9) do set "strNum=!strNum:%%i=!"
    if "%strNum%" == "" echo 全数字!
goto :eof
注意:以上代码均未测试。


作者: pengfei     时间: 2006-9-30 10:01
3742668版主对语句和参数的使用好强, 代码简洁高效, 思路独到. 值得我们很好地学习...

而我对find和findstr两个命令一直有点畏惧, 它们的执行效率是比较低的, 尤其处理的数据量大的时候速度比较慢. 这一点我是经过大量测试得出来的.

版主对findstr提的两点建议很有道理, 特别是第二点思路很好.

另外版主的代码好像都只考虑目录数最多为两个(不知道是不是我看错了), 如果目录数更多就需要改写. 我还是觉得把需要操作的根目录下的所有目录列出来判断是否全为数字要好, 而用正则表达式判断是否全为数字也会影响速度.

用版主的这一段就很好, 所以我还是坚持不使用findstr:
:IsNumber
    set "strNum=%~1%~2"
    for /l %%i in (0,1,9) do set "strNum=!strNum:%%i=!"
    if "%strNum%" == "" echo 全数字!
goto :eof

感谢3742668的精彩点评, 学习了~~~!

[ Last edited by pengfei on 2006-9-30 at 10:06 ]
作者: kmlxk     时间: 2006-9-30 11:13
仰视一下~~强人啊
作者: 3742668     时间: 2006-9-30 12:52
Re pengfei:
1.关于用findstr效率低的问题。
    同样是用findstr,但是循环内和循环外使用的效率截然不同。你所说的效率低,是因为你把它放在循环内使用,执行的次数多了,当然效率就低了。如果放在循环外面执行,可以大胆地说,绝对比你写代码自己完成相应功能要快得多。
2.关于只能处理两层目录的问题。
     提示一下:for %%? in (!strDir!) do strTmp=%%? !strTmp!执行后,如果路径为c:\111\222\333\444,则strTmp的内容会是:"444" "333" "222" "111" c:"
作者: pengfei     时间: 2006-10-1 03:44


  Quote:
Originally posted by 3742668 at 2006-9-29 01:49:
@echo off
    set strOldDir=%cd%
    set strRegExp=".*\\[0-9]*\\[0-9]*$"
rem set strRegExp=".*\\[0-9]*$"
    set strFileExtension=*.wmv *.rm *.rmvb *.avi *.mp3 *.wma *.wav
    for /f "delims=" %%i in ('dir /ad /s /b ^| findstr /rc:%strRegExp%') do cd "%%i" && echo %%i && dir /b %strFileExtension%
rem for /f "delims=" %%i in ('dir /ad /s /b ^| findstr /rc:%strRegExp%') do cd "%%i" && del %strFileExtension%
    cd %strOldDir%
pause

这段代码效率非常高, 比13楼和14楼代码的执行效率高许多, 比15楼的代码也要快.

3742668版主能解释一下 findstr /rc:".*\\[0-9]*\\[0-9]*$" 这一句的含意吗?

这一段代码的大概意思是不是列出当前目录下所有的子目录, 判断最底层目录是否全为数字, 如果是将删除文件夹下的所有影音文件?

如果是这样就不符合楼主提出的. d:\music\1234\1345 (当前目录为d盘), 只要目录名不为数字这样的文件夹下的文件都不能删.

所以还是列出当前目录下所有的文件夹名, 判断其是否全为数字, 如果路径中出现非数字就不执行删除操作要安全一些.

[ Last edited by pengfei on 2006-10-1 at 03:55 ]
作者: 3742668     时间: 2006-10-1 12:24
Re pengfei:
    1.findstr /rc:".*\\[0-9]*\\[0-9]*$"表示搜索字符串的内容为:[任意内容]+[\]+[至少一个数字]+[\]+[至少一个数字][结束],在findstr的搜索字符中,遇到特殊字符需要用\来转义,例如\就应该写成:\\
    2.这段代码的作用是,如果当前目录下的子目录中,最后两层目录为全数字组成的话,则删除最底层目录下所有的影音文件。
    3.很显然,你和我对于楼主(这个可耻的家伙,咱为他争得脸红脖子粗,他给咱玩失踪,呵呵)的意图理解并不一样。
    你的理解为:最低两层全数字,且父目录中也是全数字(拗口,也就是当前目录下的每层子目录都全数字)。
    而我的理解为:最低两层全数字,父目录不管。
    不过,不管楼主的意图是什么,都不重要。但是,对于你所说的"所以还是列出当前目录下所有的文件夹名, 判断其是否全为数字,",个人觉得不是很必要:
1.findstr部分:
@echo off
    set strOldDir=%cd%
    set Filter="%cd:\=\\%\\[0-9]*\\[0-9]*$"
rem set Filter=".*\\[0-9]*\\[0-9]*$"
rem set Filter=".*\\[0-9]*$"
    set FileExtension=*.wmv *.rm *.rmvb *.avi *.mp3 *.wma *.wav
    set "cmd1=dir /ad /s /b ^| findstr /rc:"
    set "cmd2=cd "%%i" && echo %%i && dir /b"
    for /f "delims=" %%i in ('%cmd1%%Filter%') do %cmd2% %FileExtension%
    cd %strOldDir%
pause
2.非findstr部分:
for .... do (
    set "strPath=%%i"
    set "strPath=!strPath:*%cd%\=!"
    call :dosomething "!strPath:\="
    )
goto :eof

:dosomething
    rem 这里除了21F中过滤数字的代码以外
    rem 还需要对空格进行过滤
    rem 参数要用%~*而不是%~1%~2
goto :eof
   
纸上又谈了半天兵,闪人睡觉去也。
作者: pengfei     时间: 2006-10-2 20:09


  Quote:
Originally posted by tide2046 at 2006-9-28 05:34:
现在上司给的指示是:只能是父目录为数字的文件夹里的影音文件和其子目录名同样为数字的文件夹里的影音文件才可以删

即:比如 D:/music/123/*.rm   这样的不能删

而:D:3213/321/*.rm   这样的需要删除

呵呵~ 楼主潜水这么久也不冒个泡.

我对他上面给出的提示的理解是, D盘根目录下的music文件夹下的文件不能删, 而music目录下又出现了数字命名的文件夹. 这样3742668版主从最底层目录匹配纯数字是危险的, music目录下的123文件夹符合条件, 而提示是这样的目录下的文件不能删.

所以我认为从当前根目录开始匹配最为安全, 并且楼主提到只能是父目录为数字以及子目录同样为数字的文件夹里的影音文件才可以删.

3742668版主提示的还需要对空格进行过滤, 这个很重要. 我在想为什么你的代码执行这么快, 有点纳闷了, 而13楼namejm版主的代码和14楼的代码为同样的正则表达式却慢很多. (虽然findstr在FOR循环中, 但我认为不是这个原因)

21楼的findstr是dir /s 后接一个管道命令连接, 而13,14楼的代码是先dir /s 后进行处理再echo后接一个管道命令. 难道是这个原因???
作者: pengfei     时间: 2006-10-2 20:10
CLS
不好意思, 我这网络真差, 刚连上就掉线了, 一连提交几次才成功, 一看居然提交了两次重复内容. 汗...
[ Last edited by pengfei on 2006-10-2 at 20:22 ]
作者: iPoint     时间: 2010-1-18 16:25


  Quote:
Originally posted by 3742668 at 2006-10-1 12:24:
Re pengfei:
    1.findstr /rc:".*\\[0-9]*\\[0-9]*$"表示搜索字符串的内容为:[任意内容]+[\]+[至少一个数字]+[\]+[至少一个数字][结束],在findstr的搜索字符中 ...

3742668這個版主還在嗎。。好仰慕。。收藏寶貼