[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖
  1. @echo off
  2. cd /d "%~dp0"
  3. set str=symlink
  4. for /f "delims=" %%d in ('dir /b /s /ad ^|sort /r') do (
  5. move "%%d\*.%str%" "%%d\.."
  6. del /q "%%d\*"
  7. rd "%%d"
  8. pause
  9. exit
  10. )
复制代码
bat小白,请多指教!谢谢!

TOP

回复 3# mmm8422616


  
  1. @echo off
  2. cd /d "%~dp0"
  3. set str=symlink
  4. for /f "delims=" %%d in ('dir /b /s /ad') do (
  5. dir /b /ad "%%d" |findstr . 1>nul || set _"%%d"=1
  6. )
  7. for /f "delims=" %%d in ('dir /b /s /ad') do (
  8. if defined _"%%d" (
  9. if exist "%%d\*.%str%" (
  10. move "%%d\*.%str%" "%%d\.."
  11. del /q "%%d\*"
  12. rd "%%d"
  13. )
  14. )
  15. )
  16. pause
复制代码
bat小白,请多指教!谢谢!

TOP

回复 11# mmm8422616


  1. @echo off
  2. cd /d "%~dp0"
  3. set str=symlink mp4 mkv
  4. for /f "delims=" %%d in ('dir /b /s /ad') do (
  5. dir /b /ad "%%d" |findstr . 1>nul || set _"%%d"=1
  6. )
  7. for /f "delims=" %%d in ('dir /b /s /ad') do (
  8. if defined _"%%d" (
  9. for %%x in (%str%) do (
  10. if exist "%%d\*.%%x" (
  11. move "%%d\*.%%x" "%%d\.."
  12. set _"%%d"=
  13. )
  14. )
  15. if not defined _"%%d" (
  16. del /q "%%d\*"
  17. rd "%%d"
  18. )
  19. )
  20. )
  21. pause
复制代码
bat小白,请多指教!谢谢!

TOP

回复 8# qixiaobin0715


   谢谢大佬指点!没考虑文件夹过多情况,如果文件夹数量成百上千、甚至过万,可能使用dir 都会影响效率;如果文件夹过多,目标文件且多存在于末级文件夹,使用dir /a-d 初步筛选可能符合条件的文件夹,可能更快点,具体看楼主实际情况吧:lol
bat小白,请多指教!谢谢!

TOP

回复 17# aloha20200628


    谢谢大佬指点!
如果某目录下子目录众多,使用call + for /d 及时退出遍历应该也行,不过没有dir 灵活,不能识别隐藏目录

  1. @echo off
  2. call :1 "C:\0\1\2\3"
  3. if %errorlevel% equ 2 (
  4. echo "C:\0\1\2\3" 是末级目录
  5. )
  6. pause & exit
  7. :1
  8. for /r "%~1" /d %%e in (*) do (
  9. exit /b 1
  10. )
  11. exit /b 2
复制代码
bat小白,请多指教!谢谢!

TOP

我测试了一下,只判断、打印、计数末级目录,以我的c盘实际情况为例,共有末级目录2200个
  1. 17楼方法一
  2. 11:05:21.13
  3. 11:05:54.99
  4. 耗时 33s
  5. 17楼方法二
  6. 10:56:52.10
  7. 10:57:31.35
  8. 耗时 39s
  9. 17楼方法三
  10. 10:55:53.43
  11. 10:56:24.59
  12. 耗时 31s
  13. 18楼方法
  14. 10:59:32.28
  15. 10:59:45.13
  16. 耗时 13s
复制代码
bat小白,请多指教!谢谢!

TOP

回复 22# terse


   大佬,我在测试效率的时候发现,遇到文件夹名称,如 新建文件夹 (2),则会出错
  1. @echo off
  2. call :listdir "%cd%"
  3. pause
  4. exit
  5. :listdir
  6. for /d %%d in ("%~1\*") do set "d=%%d"&call :listdir "%%d"
  7. if defined d (
  8. echo %d%
  9. )
  10. set "d="
复制代码



echo %d%结果,右括号消失了
  1. D:\\1\新建文件夹 (2
复制代码
bat小白,请多指教!谢谢!

TOP

本帖最后由 77七 于 2024-4-12 16:20 编辑

回复 24# 77七


   我找到原因了,去掉()则正确
  1. if defined d echo %d%
复制代码


这个if 和 () 真是纠缠不清啊,这都能出错...这个直接颠覆了我的认知,以前一直以为明着写才会出错
再次验证
  1. @echo off
  2. set str=D:\\1\新建文件夹 (2)
  3. if defined str (
  4.         echo %str%
  5. )
  6. pause
复制代码


结果还是错的

幸好以前跟aloha20200628大佬学了一招,使用set /p=""<nul,保留特殊字符,双引号直接把()打出原形
  1. @echo off
  2. set str=D:\\1\新建文件夹 (2)
  3. if defined str (
  4.         set /p="%str%"<nul
  5.         echo=
  6. )
  7. pause
复制代码


结果正确
想到aloha20200628大佬提到 set /p=""<nul无法保留前置空格,看来也不是个完美办法
  1. @echo off
  2. set str= D:\\1\新建文件夹 (2)
  3. if defined str (
  4. for /f "delims=" %%x in ("%str%") do (
  5. echo %%x
  6. )
  7. )
  8. pause
复制代码


难道只能这样了?...
bat小白,请多指教!谢谢!

TOP

回复 26# terse


   谢谢大佬指点!引号确实能解决此例中的显示问题,但我想到遇到其它问题的时候可能不需要引号
我又试着开启变量延迟扩展,结果正确
  1. @echo off
  2. set str=D:\\1\新建文件夹 (2)
  3. if defined str (
  4. setlocal enabledelayedexpansion
  5. echo !str!
  6. endlocal
  7. )
  8. pause
复制代码
bat小白,请多指教!谢谢!

TOP

本帖最后由 77七 于 2024-4-12 16:52 编辑

回复 28# terse


   谢谢大佬指点!特殊字符与变量延迟扩展的关系真是奇妙!开启变量延迟扩展不当则会漏掉特殊字符“!”本身,但更多情况是成就了更多特殊字符。
bat小白,请多指教!谢谢!

TOP

本帖最后由 77七 于 2024-4-13 18:55 编辑

回复 30# aloha20200628


   大佬,for /r "%~1"是我随手写的,如果目录非常庞大,dir /b /ad 没有/s ,没有遍历子目录,显然有失公平,使用/r应该徒增了很多无用功吧,以前我做过测试,for /r 的遍历机制,当处理到第一个(还是第二个,记不清了)目录的时候,大概已经完成了700多个目录的列举,(数据记得不是很清楚了)不知道这是否拉低了效率
麻烦大佬您再测试一下,for /d

  1. set "n="&for /d /r %%d in (*) do (
  2.         set "k=" &(call :xxx "%%~d" k)
  3.         if not defined k set/a "n+=1"
  4. )
  5. echo,发现 %n% 个末级目录&exit/b
  6. :xxx
  7.         for /d %%e in ("%~1\*") do (set "%~2=1"&exit/b)
  8.         exit/b
复制代码
bat小白,请多指教!谢谢!

TOP

本帖最后由 77七 于 2024-4-13 19:31 编辑

回复 30# aloha20200628


   大佬,我把c盘复制了5次66000文件,16000目录,末级目录10000个
测试了方法1、4,结论和大佬的一致
call +for /d 7分钟,dir 4分钟。call cpu占用比dir低。感觉dir在全力跑,call+for /d有点散步的意思
bat小白,请多指教!谢谢!

TOP

本帖最后由 77七 于 2024-4-14 01:00 编辑

回复 34# terse


  之前测试效率,被if () 搞中断了...
现在我测试了一下,大佬您的代码效率很高,测试样本仍然是32楼的那些,耗时20秒左右

样本说明:复制了整个c盘小于10kb的文件及目录,并手动复制了几次

可能是因为样本比较特殊,使用中出现了一些小插曲,大佬的代码遗漏了 ”用户\admin\appdata“ 目录下的末级目录
,到
  1. "f:\测试\Users - 副本 - 副本 (2)\admin\3D Objects"
复制代码
就结束了。

而dir 和call +for /d 均列出了
  1. "F:\测试\Users - 副本 - 副本\admin\AppData\Local\Microsoft\PowerShell\7.2.7"
复制代码
bat小白,请多指教!谢谢!

TOP

本帖最后由 77七 于 2024-4-14 01:57 编辑

我找出原因了
用户\admin\appdata
这个目录使用for /r /d 能够遍历出来,使用for /d 则不能
惭愧惭愧,学习不思考......appdata下的子目录不具有隐藏属性,所以for /r /d遍历了appdata下的子目录,仍没有遍历出appdata
bat小白,请多指教!谢谢!

TOP

返回列表