Board logo

标题: [文件操作] 批处理检测某盘符下所有的空文件夹 [打印本页]

作者: youxi01    时间: 2008-1-4 23:50     标题: 批处理检测某盘符下所有的空文件夹

用批处理检测某盘符下所有的空文件夹
包括子目录,并将该空文件夹的路径显示出来.
作者: 随风    时间: 2008-1-5 01:06

缺点:若某空文件夹下有空文件夹,会把这个父文件夹当作非空文件夹。
:
  1. @echo off
  2. for /f "delims=" %%a in ('dir /b/s/ad^|sort /r') do (
  3.   dir /b "%%a"|findstr .>nul|| echo %%a
  4. )
  5. pause
复制代码

作者: 随风    时间: 2008-1-5 01:26


原来联盟里早有精彩的代码了,我的真是献丑了。
作者: youxi01    时间: 2008-1-5 07:48     标题: 回复 3# 的帖子

哦,是吗?我也不知道哦
不过看2F的代码效率确实不是很高...
作者: youxi01    时间: 2008-1-5 07:48

用递归的方法可能会好很多
作者: 随风    时间: 2008-1-5 11:39

利用 namejm 在cn-dos里的一段代码
:
  1. @echo off
  2. for /f "delims=" %%i in ('dir/b/s/ad') do call :lis "%%i"
  3. pause
  4. :lis
  5. set flag=
  6. for /f "delims=" %%a in ('dir/a/b %1') do set flag=1
  7. if not defined flag echo %~1
  8. goto :eof
复制代码

[ 本帖最后由 随风 于 2008-1-5 12:18 编辑 ]
作者: youxi01    时间: 2008-1-5 18:19

个人觉得,namejm的代码效率还有挖掘的潜力。
因为namejm在代码中,几乎对所有的文件夹都进行了检测,举例说明:
现有一父文件夹f:\test,一子文件夹f:\test\test。
在namejm的代码中,不管是子文件夹还是父文件夹都会去检测是否为空(父文件夹肯定不为空),这样,会导致效率打折扣。于是,个人就尝试用递归的方法找出 那个 不含任何子文件夹的 文件夹,然后只要检测这些文件夹是否是空文件夹就行了,测试代码:
  1. @echo off&setlocal enabledelayedexpansion
  2. for /d %%i in (f:\*) do call :Check "%%i"
  3. for /f "delims=" %%i in (test.txt) do (
  4.      set flag=0
  5.      for /f "delims=" %%j in ('dir /a-d /b %%i 2^>nul') do set flag=1
  6.      if !flag! EQU 0 echo %%i为空文件夹)
  7. pause>nul
  8. :Check
  9. set "var=%~1"
  10. set flag=0
  11. for /D %%i in ("%~1\*") do (
  12.       set flag=1
  13.       call :Check "%%i"
  14. )
  15. if %flag% EQU 0 (>>test.txt echo "%var%"& set flag=1)
复制代码
不过效率还不是很高,较namejm的略高。
不过,两种方法各有优缺点(而且检测结果有些出入,原因正在查...):
namejm的代码优点:可以检测系统文件夹;代码简洁;缺点:速度略慢;

上面的递归算法优点:速度稍快;缺点:不能探测系统目录,如:回收站等;

附:两种方法检测结果
namejm的代码:
  1. 18:09:59.12
  2. F:\System Volume Information\_restore{CD2BF03E-A00F-4EFC-A572-06BD79233DB7}
  3. F:\2\新建
  4. F:\2\新建文件夹\新建文件夹\新建文件夹1
  5. 找不到文件
  6. F:\RECYCLER\S-1-5-21-1060284398-813497611-13438020022-500.
  7. 找不到文件
  8. F:\RECYCLER\S-1-5-21-1060284298-813497611-13438020086-500\S-1-5-21-1064224258-81
  9. 3597681-13430823629-500.
  10. 找不到文件
  11. F:\RECYCLER\S-1-5-21-1060284298-813497611-13438020086-500\S-1-5-21-1064442258-81
  12. 3597862-13230823629-500.
  13. F:\Recycled\Df1
  14. F:\Recycled\Df2
  15. F:\Recycled\Df91
  16. F:\Recycled\Df42\班主任工作
  17. F:\Recycled\Df42\10班成绩
  18. F:\Recycled\Df42\班会课(修改)\大学照片\班会课~2\大学照片
  19. F:\Recycled\Df62\芳香烃 示例1
  20. F:\办公\CN-DOS批处理精华贴(2007-A)(IE7)
  21. F:\办公\经典代码\经典代码\系统优化\C盘个人资料转移器\Desktop
  22. F:\办公\经典代码\经典代码\系统优化\C盘个人资料转移器\Favorites
  23. F:\办公\经典代码\经典代码\系统优化\C盘个人资料转移器\My Documents
  24. F:\办公\经典代码\经典代码\系统优化\C盘个人资料转移器\OE
  25. F:\办公\经典代码\经典代码\系统优化\C盘个人资料转移器\Temp
  26. F:\办公\★化学★\化学反应原理课件\第二章\化学平衡\平衡图像(第四课时)
  27. 18:11:18.35
复制代码
递归算法运行结果:
  1. 生成临时文件18:15:09.23.....
  2. 生成临时文件完成.....
  3. "f:\2\新建文件夹\新建文件夹\新建文件夹1"
  4. "f:\2\新建"
  5. "f:\办公\经典代码\经典代码\系统优化\C盘个人资料转移器\Desktop"
  6. "f:\办公\经典代码\经典代码\系统优化\C盘个人资料转移器\Favorites"
  7. "f:\办公\经典代码\经典代码\系统优化\C盘个人资料转移器\My Documents"
  8. "f:\办公\经典代码\经典代码\系统优化\C盘个人资料转移器\OE"
  9. "f:\办公\经典代码\经典代码\系统优化\C盘个人资料转移器\Temp"
  10. "f:\办公\CN-DOS批处理精华贴(2007-A)(IE7)"
  11. "f:\办公\★化学★\化学反应原理课件\第二章\化学平衡\平衡图像(第四课时)"
  12. "f:\办公\PowerpointMOBAN\PowerpointMOBAN\Groovy Baby"
  13. "f:\办公\PowerpointMOBAN\PowerpointMOBAN\3 New free PowerPoint Template Designs"
  14. "f:\办公\PowerpointMOBAN\PowerpointMOBAN\Preprogrammed PowerPoint Templates"
  15. "f:\办公\PowerpointMOBAN\PowerpointMOBAN\Sunrise and Sunsets, Clouds"
  16. ========完成18:16:06.57==============
复制代码

作者: youxi01    时间: 2008-1-5 18:30     标题: 回复 2# 的帖子

这里用findstr还不如设置 标志?!如果,含有文件则+1
作者: youxi01    时间: 2008-1-5 23:50     标题: 回复 9# 的帖子

有几个地方你理解错误了:
1、
标签下面的for已经检测出了,文件夹是否为空,flag等于0时不就代表此文件夹为空吗?  那么创建临时文件和后面的for岂不是多余的了吗?

这个 检测的时候,检测出的不是空文件夹,而是最后一级文件夹,也就是这个文件夹里再没有文件夹,但不表示这个文件夹里没有文件!!
2、
另:if %flag% EQU 0 (>>test.txt echo "%var%"& set flag=1)
  这句中的set flag=1 有什么用?

这个要仔细思考了,如果不设置flag的话,会重复显示结果的(递归调用的时候,跳出一层for,它就显示一次,有多少层for,就重复显示多少次)
作者: 随风    时间: 2008-1-6 00:12

呵呵,你回的真快啊,我马上就删除了,你还是看见了
作者: 随风    时间: 2008-1-6 00:29

:
  1. @echo off
  2. for /f "delims=" %%a in ('dir/s/a/b/ad^|sort /r') do (
  3.     if not defined flag call :loop "%%a"
  4.     if "%%a"=="%flag%" (set flag=) else call :lis "%%a"
  5. )
  6. pause
  7. :lis
  8. set num=
  9. for /f "delims=" %%a in ('dir/a/b %1 2^>nul') do set num=1
  10. if not defined num echo %~1
  11. goto :eof
  12. :loop
  13. for /f "tokens=1* delims=\" %%c in (%1) do (
  14.   if not "%%d"=="" call set flag=%%flag%%\%%c
  15.   call :loop "%%d"
  16. )
  17. set flag=%flag:~1%
  18. goto :eof
复制代码

作者: 随风    时间: 2008-1-6 01:01

即是空文件夹,何不先删除再创建呢?
:
  1. @echo off
  2. for /f "delims=" %%i in ('dir/s/a/b/ad^|sort /r') do (
  3.    rd "%%i"2>nul&&md "%%i"&&echo %%i
  4. )
  5. pause
复制代码

[ 本帖最后由 随风 于 2008-1-6 01:02 编辑 ]
作者: youxi01    时间: 2008-1-6 08:05

呵呵,删除再创建?!
好思路!!
作者: ww0000    时间: 2024-8-29 17:36

回复 2# 随风

老师,能不能改成,输出 txt 路径?
作者: ww0000    时间: 2024-8-29 18:07

回复 1# youxi01


   代码能分享一下 吗?谢谢
作者: 77七    时间: 2024-8-29 19:08

回复 14# ww0000


  
  1. @echo off
  2. (for /f "delims=" %%a in ('dir /b/s/ad^|sort /r') do (
  3.   dir /b "%%a"|findstr .>nul|| echo %%a
  4. ))>Out.txt
  5. pause
复制代码

作者: ww0000    时间: 2024-8-30 09:02

回复 16# 77七

谢谢帮助!!
作者: aloha20200628    时间: 2024-8-30 20:26

本帖最后由 aloha20200628 于 2024-8-30 20:40 编辑


批量检查子目录是否为空,又是一个老话题,看了一大把中外老帖,句式版本繁杂,最后简化为两点:
一。用 dir /b/a 方法检测比较可靠,但遭遇大数据目录会明显降速,老帖中一个速度略快的版本如下
  1. for /r /d %%F in (*) do dir /b/a "%%F" | find /v "" >nul || echo,%%~fF
复制代码
还有一个powershell版本,但速度比2楼代码还慢
  1. powershell -c "gci -dir -r | ? {[io.directory]::getfilesystementries($_.fullname).count -eq 0} | %% {$_.fullname}"
复制代码
二。用 rd+md 连环方法会明显提速,但在同一 for 循环内执行,表现有点‘奇葩’,即 rd 的返回值失稳,会影响其后的 && || 判断以及 exist 状态;有时还会出现后续 md 丢步的结果...

     因为看上了方法二的速度优势,反复调试出一个版本,主要是采用 rd 和 md 分用两个 for 循环各自完成的方案,其可靠性明显改善,在此分享仅供参考...
  1. @echo off
  2. (for /f "delims=" %%d in ('dir /s/b/ad^|sort /r') do rd "%%d"&&echo,%%d)>"空目录列表.txt" 2>nul
  3. for /f "delims=" %%d in (空目录列表.txt) do (md "%%d"&echo,%%d 》空目录) 2>nul
  4. pause&exit/b
复制代码





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