![]() |
中国DOS联盟-- 联合DOS 推动DOS 发展DOS --联盟域名:www.cn-dos.net 论坛域名:www.cn-dos.net/forum |
| 游客 | 登录 | 注册 | 会员 | 搜索 | 中国DOS联盟 |
|
中国DOS联盟论坛 现在时间是 2026-08-02 02:26 |
共 48,037 主题排行 / 350,122 发帖 / 今日 2 篇 / 48,250 会员排行 |
| DOS批处理 & 脚本技术(批处理室) » 一个关于随机获取文件名的问题. |
| 可打印版本 17,867 / 54 |
| 第31楼 zh159 | 发表于 2006-07-28 09:48 |
| 金牌会员 发帖 1,467 积分 3,687 | |
|
voiL 在 10 楼说的无奈何版主代码"编号"问题,估计 voiL 是在“echo %random%:%*”一行后面>>List.txt了应该是在“@echo %%b”后面>>List.txt
看 25 楼 |
|
| 第32楼 220110 | 发表于 2006-07-28 10:01 |
| 荣誉版主 发帖 313 积分 718 | |
|
获取目录下所有的mp3文件数量,用 for /r %%i in (*.mp3) do set /a n+=1 来取代:
[1] for /f "tokens=1 delims= " %%i in ('dir *.mp3^|find "个文件"') do set 文件数量=%%i [2] dir /b *.mp3 | findstr /n "." >tem.txt for /f "tokens=1 delims=:" %%g in (tem.txt) do set maxnum=%%g [3] for /f "delims=" %%i in ('dir /b /a-d') do @call :sub %%i 是否效率会高点?请willssort作下深入剖析. |
|
| 第33楼 namejm | 发表于 2006-07-28 10:32 |
| 荣誉版主 发帖 1,737 积分 5,226 来自 成都 | |
Originally posted by zxcv at 2006-7-28 09:42: 如果只是加注释,可以在语句的上一行或下一行用 :: 注释内容 或者 rem 注释内容 的格式。 [ Last edited by namejm on 2006-7-28 at 10:35 ] |
|
| 第34楼 namejm | 发表于 2006-07-28 14:16 |
| 荣誉版主 发帖 1,737 积分 5,226 来自 成都 | |
|
和bagpipe探讨了无奈何版主25楼的代码,发现这段代码还有可精简的地方,把bagpipe精简后的代码发一下:
1、 2、 |
|
| 第35楼 doscc | 发表于 2006-07-28 16:13 |
| 中级用户 发帖 93 积分 256 来自 广东 | |
Originally posted by 无奈何 at 2006-7-27 23:51: 无奈兄 的代码 真的很高明! 不愧是版主! 高明之处 ('"%~0" $^|sort') 和 echo %random%:%* 前乎后应也! 简单解析一下代码: 获得所有文件 在每个文件前标上 随机数 再排列 过虑输出! [ Last edited by doscc on 2006-7-28 at 16:18 ] |
|
| 第36楼 doscc | 发表于 2006-07-28 16:22 |
| 中级用户 发帖 93 积分 256 来自 广东 | |
|
Re: namejm & bagpipe
call echo %%random%%:%%%%i 这句用得很好! |
|
| 第37楼 willsort | 发表于 2006-07-28 19:49 |
| 元老会员 发帖 1,512 积分 4,432 | |
Originally posted by 220110 at 2006-7-28 10:01: Re 220110『第 32 楼』: 关于上述几段代码的问题,我有以下几点浅见: 1、从算法角度上来看,各段代码的时间复杂度是一致的,所以他们真正的运行效率主要取决于系统支持上的细节; 2、从代码角度上来看,兄的代码效率上的优势在于没有使用文本的的输入输出操作;而众所周知的是,I/O向来是影响代码效率的瓶颈之一,这是其他的几段代码所不及的。在其他的代码中,代码的效率应该强于代码,因为代码不仅对dir的输出文本作了编辑(加行号),而且for/f的文本处理量也明显大于代码;至于代码的用法,因为涉及到了批处理的递归调用(其本质是数据读取),所以其效率也低于代码。 3、但在实际的测试中,结果并不完全像2所分析的那样。在小规模的测试中(Audio目录,文件数746),兄的代码效率最高(140ms),其次却并非代码(234ms),而是代码(218ms)。分析其结果,原因就在于,代码并非直接用for/f分析findstr的结果,而是使用了临时文件temp.txt,而操作系统为了改善文件IO的效率,会在内存中开辟出相应的文件IO缓冲区,以提高文件的访问速度,而代码因为无法“享受到这种优惠政策”而导致了初段赛跑的落后。这是一个典型的因为系统特性而影响代码效率的例子。 4、而在一些大规模的测试中(整盘测试,文件数>60000),情况再次发生了变化。首次的测试结果是,兄的代码>代码>代码,但是随后的测试中,情况就变成了代码>兄的代码>代码。其原因在于操作系统针对dir等大规模的文件I/O行为设计了位于硬盘上的预存取(Prefetch)机制,由于兄的代码无法“借光”,所以在旗开得胜之后便一蹶不振了。而代码的因为规模的增大暴露出其文件处理算法上的落后。这是另一个比较典型的因为系统特性而影响代码效率的例子。 5、在实用角度上来看,兄的代码因为for不遍历隐藏和系统属性的文件,所以其结果会在一些复杂的应用场合中发生偏差。代码中因为缺少/a-d开关,因为会将目录也计入文件数中。另外,如果在代码的dir开关中,加入/w会对效率的提升有些帮助,而加入开关/-c,则可以去除结果中的逗号分隔符。而如果将代码改为代码的临时文件机制,则效率可以得到进一步提升。所以,综合各方案的我的修改后的方案如下: [ Last edited by willsort on 2006-7-29 at 01:27 ] |
|
| 第38楼 220110 | 发表于 2006-07-29 00:23 |
| 荣誉版主 发帖 313 积分 718 | |
|
Re willsort:
不知道你有没有测试深层多层子目录下的情况? 总觉得for /r 比 dir /b /a:-d 来得效率要高,排除你的第五点提的系统属性影响。 我只在根目录对系统盘测试了下,系统盘算足够多的文件和足够深的路径了吧;暂无其它新测试办法和环境对比。 Re namejm & bagpipe: 你们确实不错!还能精简。 只是,你们忽略了无奈何的初衷——不使用临时文件。 看你们不用临时文件,还能怎么精简!!激将一下,哈 [ Last edited by 220110 on 2006-7-29 at 00:25 ] |
|
| 第39楼 willsort | 发表于 2006-07-29 01:46 |
| 元老会员 发帖 1,512 积分 4,432 | |
|
Re 220110:
在你回复之前,就开始对原稿进行重新编辑,之后才看到你的回复,其中对你提到的新问题略有提及。 至于 namejm & bagpipe 兄 对 无奈何兄的代码精简,其实并未涉及临时文件,代码中的list.txt,实际上是保存结果数据的文件,而无奈何兄的原方案是直接将他们输出至控制台上的。 而无奈何兄的让namejm兄所难以理解的if/lse结构,才真正是避免临时文件的关键。也就是说,如果使用临时文件,则可以不使用if/lse结构,比如我编辑过的以下代码。 另外,无奈何兄的代码最突出的特点,不在于简洁或者晦涩,而在于其反其路而行之的高效算法,不再去控制随机数的生成,而是去控制列表的生成,这是其它几段代码都无法比及的。 [ Last edited by willsort on 2006-7-29 at 01:48 ] |
|
| 第40楼 namejm | 发表于 2006-07-29 20:44 |
| 荣誉版主 发帖 1,737 积分 5,226 来自 成都 | |
|
看了willsort版主39楼的代码,才知道制造空文本文件还可以用cd.>这样的方法,开眼了。
无奈何版主的代码确实很高明,抛开按顺序打印行号之后再乱序选取的常规思路,而直接乱序命名行号再重列,是乱中求顺而达到乱序排列的目的,此法的效率和常规解法的效率不是同一个数量级的。不过,因为调用自身的缘故,去掉开头的@echo off一句之后,就会得到错误的结果,因此,这段代码只能作为一个独立的脚本来使用,而不能作为某个脚本中内部的子段来调用。如果能做出可循环调用的子段的话,就十分完美了。 搭个车问个问题:重定向符号<和>在同一条语句中接连使用的方法,不怎么熟悉,哪位能讲解一下不?主要讲一下使用环境、有没有什么条件的限制等。 |
|
| 第41楼 无奈何 | 发表于 2006-07-29 22:17 |
| 荣誉版主 发帖 356 积分 1,338 | |
|
还是 willsort 兄的总结最点到要害。
不好意思的说,我给出的代码我并没有太多的关注效率问题,只是不想生成临时文件。这段代码只是一个典型的递归调用的例子,看讨论已经解释的比较清楚了,不再多言。如果在不在意生成临时文件的情况下 willsort 兄 39 楼给出的代码无疑是最简单且容易操控的。 关于 namejm 兄与 bagpipe 兄的精简我是很喜欢这种精神的,可以改善代码的质量,提高代码的编写水平,并且不时还会有新的发现。当然这其中会有代码书写习惯的问题,就像我非不得以的情况我会尽量避开延缓环境变量的使用,而更喜欢调用外部代码段,这样的程序结构看起来更好看一点,效率问题我还没有深入的研究过。再者 namejm 兄 34 楼 代码段 2、中 %%random%%:%%%%i 句是有问题的,当含有 1.mp3、2.mp3 这样的文件时文件名会丢失,原因是参数 i 多次被转义,修正是去掉两个 % ,参见 39 的代码。 |
|
| 第42楼 HUNRYBECKY | 发表于 2006-12-10 03:13 |
| 银牌会员 发帖 442 积分 1,179 | |
|
willsort兄的代码的确精简也很精彩,但是有个问题。如果要获取某个盘下所有子目录的文件则有问题,结果输出只有盘符。
|
|
| 第43楼 zh159 | 发表于 2006-12-10 14:29 |
| 金牌会员 发帖 1,467 积分 3,687 | |
|
把俺最新的也加入这贴吧^_^
|
|
| 第44楼 3742668 | 发表于 2006-12-10 14:57 |
| 荣誉版主 发帖 718 积分 2,013 | |
|
利用sort /+n 也能一定程度上的随即列表。
它要求文件名相似度不能太高。 |
|
| 第45楼 qzwqzw | 发表于 2006-12-10 16:05 |
| 银牌会员 发帖 636 积分 2,343 | |
|
可以考虑使用不同的%num%反复sort来增大随机度。
|
|
| 上一页 1 2 3 4 下一页 |
|
[ 联系联盟系统管理团队 -
中国DOS联盟 -
标准版 ] Sponsored by ifanr Inc | © 2001–2023 |