[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖
回复 1# mmm8422616

一楼题意是指“最后一级目录(不再含子目录)”,如是则代码也许可进一步简化...
以下代码假设最后一级目录为 d:\a\aa\aaa
  1. @echo off &set "_cd=d:\a\aa\aaa"
  2. cd /d "%_cd%" &(for %%F in ( "symlink" "jpg" "nfo" ) do move /y "*.%%~F" "..") 2>nul
  3. cd ".." & rd /s/q "%_cd%" &pause &exit/b
复制代码

TOP

本帖最后由 aloha20200628 于 2024-4-11 18:37 编辑

回复 12# mmm8422616
处理(删除)“多个” 末级目录和处理(删除)“每个” 末级目录可不是一回事

TOP

回复 16# 77七

单论判断一个指定目录(例如 C:\0\1\2\3)是否包含子目录,至少有三个方法如下
如果指定目录中确实没有子目录,各方法耗时差别几乎无感,但若真有好多多子目录,那差别就不一般了,方法三可是要用纯P去逐个遍历啊 所以中外老帖中还是用方法一或方法二为多。
  1. ::方法一
  2. dir /b/ad "C:\0\1\2\3" | find /v "">nul || echo,是末级目录
  3. ::方法二
  4. dir /b/ad "C:\0\1\2\3" | findstr ".">nul || echo,是末级目录
  5. ::方法三
  6. set "n=" &for /f "delims=" %%j in ('dir /b/ad ""C:\0\1\2\3"') do set "n=1"
  7. if not defined n echo,是末级目录
复制代码
1

评分人数

    • 77七: 感谢分享技术 + 1

TOP

本帖最后由 aloha20200628 于 2024-4-11 22:14 编辑

回复 12# mmm8422616

以下代码会处理当前目录下所有末级目录,但假设 “仅当末级目录中确实有文件被移动后” 才删除该末级目录...
代码中第3行可增减多个被空格分隔的用双引号包裹的文件扩展名字段
  1. @echo off &setlocal
  2. (for /d /r %%d in (*) do dir /b/ad "%%~d\*" |find /v "">nul || (
  3. for %%F in ( "symlink" "jpg" "nfo" "mkv" "mp4") do if exist "%%d\*.%%F" (set/a "n=1"&move /y "%%d\*.%%F" "%%d\..")
  4. if defined n (set "n="&rd /s/q "%%d")
  5. )) 2>nul
  6. pause &exit/b
复制代码

TOP

回复 18# 77七

老帖中对call的用法议论多多,其中还有慎用甚至不用的说法... 也难为了call先生,要对调用关键词在 "行首标签/内部命令/系统命令/外部(第三方)可执行脚本和程序文件/..." 中逐一匹配择取,也不知其匹配优先权如何,反正够累的

TOP

本帖最后由 aloha20200628 于 2024-4-13 18:28 编辑


用本帖敲打一下 call 的功过,还是要看比较实际的测试结果,先看用于测试比对的四种方法,其各自代码如下
::方法1
  1. set "n="&for /d /r %%d in (*) do (
  2. dir /b/ad "%%~d\*" 2>nul | find /v "">nul || set/a "n+=1"
  3. )
  4. echo,发现 %n% 个末级目录&exit/b
复制代码
::方法2
  1. set "n="&for /d /r %%d in (*) do (
  2. dir /b/ad "%%~d\*" 2>nul | findstr ".">nul || set/a "n+=1"
  3. )
  4. echo,发现 %n% 个末级目录&exit/b
复制代码
::方法3
  1. set "n="&for /d /r %%d in (*) do (
  2. set "k=" &for /f "delims=" %%a in ('dir /b/ad "%%~d\*" 2^>nul') do set "k=1"
  3. if not defined k set/a "n+=1"
  4. )
  5. echo,发现 %n% 个末级目录&exit/b
复制代码
::方法4
  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 /r "%~1" /d %%e in (*) do (set "%~2=1"&exit/b)
  8. exit/b
复制代码
看如下测试结果
测试主目录及其文件和子目录体量                方法1耗时/方法2耗时/方法3耗时/方法4耗时(耗时单位=秒)
c:\a1 148,814 个文件,32,751 个文件夹  255/275/783/1149
c:\a2   30,262 个文件,  3,281 个文件夹  21/24/26/14
c:\a3   28,159 个文件,  2,114 个文件夹  13/15/15/6
c:\a4   16,916 个文件,  1,213 个文件夹  8/9/8/2
c:\a5     1,248 个文件,     717 个文件夹  4/5/4/1
从以上结果数据可见,小体量样本测试证明方法4有明显优势,但大样本比对就出现了逆转。
至少两点结论》
其一是用方法3即纯P跟读目录列表的效率会随样本体量增大锐减(此点其实是老生常谈不足为奇);
其二是“call乃效率大杀器”的杀气要在足够大体量的数据样本中才会凸显,在a1和a2体量之间存在一个令call从“英雄变狗熊”的拐点...
1

评分人数

    • 77七: 感谢分享技术 + 1

TOP

本帖最后由 aloha20200628 于 2024-4-13 22:11 编辑

回复 31# 77七

只要用call方法
   for /d %%d in ("%~1\*") do (set "%~2=1"&exit/b)

   for /d /r "%~1" %%d in (*) do (set "%~2=1"&exit/b)
两个句式的耗时差约在 0.07~0.05%,二者基本相当吧。
结论还是》一方面,得益于用call方法能使纯P代码从for循环中及时退出;另一方面,跑大体量数据到其“拐点”后就“怂”了...

TOP

本帖最后由 aloha20200628 于 2024-4-14 19:04 编辑


用本帖到目前为止的3种典型的call方法(代码如下)再跑了几遍测试样本,与30楼所列方法1-3测试数据合并,能有一个更全面的结论...致谢30楼和36楼
  1. ::方法4
  2. set "n="&for /d /r %%d in (*) do (
  3. set "k=" &(call :x4 "%%~d" k)
  4. if not defined k set/a "n+=1"
  5. )
  6. echo,发现 %n% 个末级目录&pause&exit/b
  7. :x4
  8. for /d /r "%~1" %%d in (*) do (set "%~2=1"&exit/b)
  9. exit/b
复制代码
  1. ::方法5
  2. set "n="&for /d /r %%d in (*) do (
  3. set "k=" &(call :x5 "%%~d" k)
  4. if not defined k set/a "n+=1"
  5. )
  6. echo,发现 %n% 个末级目录&pause&exit/b
  7. :x5
  8. for /d %%d in ("%~1\*") do (set "%~2=1"&exit/b)
  9. exit/b
复制代码
  1. ::方法6
  2. set "n="&(call :x6 "%cd%")
  3. echo,发现 %n% 个末级目录&pause&exit/b
  4. :x6
  5. for /d %%d in ("%~1\*") do (set "d=%%d"&call :x6 "%%d")
  6. if defined d (set /a n+=1)
  7. set "d="&exit/b
复制代码
方法1-6测试数据合并如下
测试主目录及其文件和子目录体量                        方法1耗时/方法2耗时/方法3耗时/方法4耗时/方法5耗时/方法6耗时(耗时单位=秒)
c:\a1 148,814 个文件,32,751 个文件夹        255/275/783/1239/1149/741
c:\a2  30,262 个文件, 3,281 个文件夹        21/24/26/14/14/4
c:\a3  28,159 个文件, 2,114 个文件夹        13/15/15/6/6/2
c:\a4  16,916 个文件, 1,213 个文件夹        8/9/8/2/2/1
可见方法6采用了递归调用,没有方法4-5代码中宿主循环开销,效率倍增,但依然会在a1-a2样本之间遭遇 ‘拐点爆胎’,被方法1-2赶超...
另一点是如36楼所说会遗漏那些受保护(如隐藏)目录...
》以上仅供参考,有兴趣者还可参考以下老帖,融合体会一下call先生的功与过...
   一。批处理之家 » BAT教程&资料 » 讨论:批处理运行效率浅谈
   二。http://bbs.bathome.net/thread-4482-1-1.html
2

评分人数

TOP

返回列表