中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --
联盟域名:www.cn-dos.net 论坛域名:www.cn-dos.net/forum
游客 | 登录 | 注册 | 会员 | 搜索 | 中国DOS联盟
中国DOS联盟论坛
现在时间是 2026-08-02 05:40
48,037 主题排行 / 350,122 发帖 / 今日 2 篇 / 48,250 会员排行
DOS批处理 & 脚本技术(批处理室) » 一个关于随机获取文件名的问题.
可打印版本  17,881 / 54
第1楼 voiL 发表于 2006-07-26 19:27
中级用户 发帖 189 积分 384
一个关于随机获取文件名的问题.
运行环境:XP SP2 CMD.

这是一个朋友询问我的问题,觉得挺有趣,但由于水平有限,我又写不出来这样的批处理.

题目是这样的:

条件:获取的名字必须是随机的,不能太有规律(不能是完全按大小或名字或建立日期等),而且有数量限制(以100个文件为例).因为以大小或名字等排列方式,我自己就写出来了,难倒我的就是随机100个文件这里.

在MP3目录下,我有数目N的MP3文件(基本都是以中文命名的),现在我想用批处理随机生成一个M3U列表,然后调用WMP来播放,以实现WMP的随机播放.

其它的我都能写,就单单是随机获取文件名这个步骤我写不出来.

不知论坛上有没感兴趣的朋友,麻烦给出个代码.

[ Last edited by voiL on 2006-7-26 at 19:37 ]
第2楼 voiL 发表于 2006-07-26 19:38
中级用户 发帖 189 积分 384
对了,如果BAT实现不了的话,可以考虑VBS,因为我对VBS不熟,没办法用VBS来写.
第3楼 namejm 发表于 2006-07-26 19:40
荣誉版主 发帖 1,737 积分 5,226 来自 成都
  用%random%和findstr /n 估计能行,主要思路就是先用findstr /n 来给MP3文件名列表编号,然后用%random%来生成随机数,然后把%random%所代表的文件名列出来。细节问题,暂时还没有考虑到,具体的代码也还没有写出来,先写个思路在这里,看各位还有什么好的思路没有。
第4楼 voiL 发表于 2006-07-26 20:48
中级用户 发帖 189 积分 384
呵呵,%random%这些参数太深奥了,还没完全弄懂,所以还没办法写出来,高手见笑了.
第5楼 zh159 发表于 2006-07-26 20:53
金牌会员 发帖 1,467 积分 3,687
WMP、WINAMP不是有随机播放功能么?这样做有点罗嗦了吧^_^
第6楼 voiL 发表于 2006-07-26 21:00
中级用户 发帖 189 积分 384
Originally posted by zxcv at 2006-7-26 20:53:
WMP、WINAMP不是有随机播放功能么?这样做有点罗嗦了吧^_^


我感兴趣的并不是它是否能实现随机播放,而是怎么去实现随机获取文件名的办法而已.由于自己搞不定,没办法之下才来请教的.
第7楼 voiL 发表于 2006-07-26 21:01
中级用户 发帖 189 积分 384
我曾经也想过通过名字、日期、大小来分别排列,然后各取前面的部分文件名来再进行名字方式排列的,但这方法只能用一次,因为每一次生成的名字还是一样的,不能实现随机取得文件名.
第8楼 zh159 发表于 2006-07-26 21:08
金牌会员 发帖 1,467 积分 3,687
我的办法:
set Name%NN%=文件名(NN为1-99)

%random:~-2%获取后两位随机数,根据后两位随机数得到%NameNN%

[ Last edited by zxcv on 2006-7-26 at 23:40 ]
第9楼 无奈何 发表于 2006-07-26 21:52
荣誉版主 发帖 356 积分 1,338
随机排序的简单做法是在文本行前增加 %random% 随机数,然后 sort 排序一下。
试试下面的脚本是否满足需要,此脚本的特点是不产生临时文件。


  1. @echo off
  2. if "%1" NEQ "$" (
  3. for /f "tokens=1,2 delims=:" %%a in ('"%~0" $^|sort') do @echo %%b
  4. ) else for /f %%i in ('dir /b /a-d') do @call :sub %%i
  5. goto :EOF
  6. :sub
  7. echo %random%:%*
  8. goto :EOF
无奈何发表于 2006-07-26 21:43
第10楼 voiL 发表于 2006-07-27 00:08
中级用户 发帖 189 积分 384
无奈何兄,你给出的方法我试过,运行结果与我之前所写的也所差无几,不能实现真正意义上的随机,因为每一次运行后所得到的结果都是一样的.

而且在输出的文件名前面都会有一组长度不一的"编号",我想这些"编号"的长度不一与文件名的不规则,对于后面的程序来说也是个问题.
第11楼 doscc 发表于 2006-07-27 02:11
中级用户 发帖 93 积分 256 来自 广东
改进后代码:
增加了:
"自动获得 文件数量 跟拒文件个数 设置随机数"
"进度显示"


[ Last edited by doscc on 2006-7-27 at 21:53 ]
第12楼 voiL 发表于 2006-07-27 05:45
中级用户 发帖 189 积分 384
经初步测试,doscc兄的代码确实有效,每次生成的列表都不一样的.

谢谢doscc兄.
第13楼 zh159 发表于 2006-07-27 15:07
金牌会员 发帖 1,467 积分 3,687
doscc 效率比较低,问题出在:
:ls
set num=%1
for /f "tokens=1,2* delims=:" %%a in ('type tem.txt') do if "%%a"=="%num%" echo %%b >> list.txt
goto :EOF

这段,%random%产生随机数后,每个随机数都要“type tem.txt”一次,搜索到"%%a"=="%num%"行才写入List.txt;如果生成的随机数“%num%”不在“type tem.txt”范围内,又得再生成随机数

我写了一段,速度快些:

@echo off
copy nul List.txt >NUL
setlocal EnableDelayedExpansion
for /f "delims=" %%a in ('dir/b/s *.mp3^|find ".mp3"') do ( 搜索当前目录下所有文件夹(可不用)
set Name=%%a
set /a N=!N! + 1
set Name!N!=!Name:%cd%=.!) 将“dir/s”生成的当前目录替换为“.”,没有“dir/s”就会自动忽略

echo.
echo 随机生成列表,请稍等...
:loop
set N=%random:~-3% ≥100个以上文件为3,<100个以下为2(位数越高速度越慢)
if "%N%" == "000" goto loop ≥100个以上文件为000,<100个以下为00
if "%N:~0,1%" == "0" set N=%N:~1%
if "%N:~0,1%" == "0" set N=%N:~1%
if %N% GTR 137 goto loop 改为文件总数量

set /a M=!M!+1
echo echo %%Name!N!%%^>^>List.txt>Temp.bat
call Temp.bat
if %M% GEQ 300 del Temp.bat & exit 生成列表的行数
goto loop


将名称 set 变量为 NameN,用”if %N% GTR 137 goto loop“控制%random%在文件数量范围内生成随机数变量N(“if "%N:~0,1%" == "0" set N=%N:~1%”去处随机数前面的“0”),用Name%N%写入列表;

以下一段自动检测文件数量设置参数

@echo off
set DIR=dir/s “dir”为只搜索当前目录,“dir/s”为搜索当前目录下所有文件夹
set 生成列表行数=200

for /f "tokens=1 delims= " %%i in ('%DIR% *.mp3^|find "个文件"') do set 文件数量=%%i
if %文件数量% GEQ 100 set X=3
if %文件数量% GEQ 100 set NN=000
if %文件数量% LSS 100 set X=2
if %文件数量% LSS 100 set NN=00
if %文件数量% LSS 10 set X=1
if %文件数量% LSS 10 set NN=0
copy nul List.txt >NUL
setlocal EnableDelayedExpansion
for /f "delims=" %%a in ('%DIR%/b *.mp3^|find ".mp3"') do (
set Name=%%a
set /a N=!N! + 1
set Name!N!=!Name:%cd%=.!)

echo.
echo 随机生成列表,请稍等...

echo :loop>Loop.bat
echo set N=%%random:~-%X%%%>>Loop.bat
echo if "%%N%%" == "%NN%" goto loop>>Loop.bat
echo if "%%N:~0,1%%" == "0" set N=%%N:~1%%>>Loop.bat
echo if "%%N:~0,1%%" == "0" set N=%%N:~1%%>>Loop.bat
echo if %%N%% GTR %文件数量% goto loop>>Loop.bat
:loop
call Loop.bat
set /a M=!M!+1
echo echo %%Name!N!%%^>^>List.txt>Temp.bat
call Temp.bat
if %M% GEQ %生成列表行数% goto :End
goto loop

:End
del Loop.bat
del Temp.bat
exit


[ Last edited by zxcv on 2006-7-27 at 15:58 ]
第14楼 namejm 发表于 2006-07-27 17:54
荣誉版主 发帖 1,737 积分 5,226 来自 成都
  11楼的代码存在一个缺憾:在列表中不能排除重复的文件名。

  以下代码可以避免这一缺憾,主要思想是:先用for+findstr /n来计算要操作的文件夹下mp3文件的个数max,然后用%random%生成随机的三位数num(假设文件的最大个数为999个);如果num大于max,则重新生成随机数num;如果num小于或等于max,且第num行的文件名还没有加入list.txt,则把编号为num的文件名写入list.txt,同时把此编号写入num.txt;如果此时num在num.txt中出现,则重新检测num……

  因为有大量的文本查询过程,此代码的效率比较低,执行的时候请耐心等待:


[ Last edited by namejm on 2006-7-28 at 09:00 ]
第15楼 doscc 发表于 2006-07-27 20:38
中级用户 发帖 93 积分 256 来自 广东
实现楼主的要求 写出来的代码效率是比较底的

我的代码 应该不会出现重复的行

因为在下面这一行做了过虑

echo %y% | findstr /r "\<%r%\>" >NUL || set y=%y% %r% & call :ls %r%
y 记录每个不一样的 随机数

当 r 不在 y 中出现时 就 记录 r 并 调用 :ls 把 tem.txt 中的第 r 行 追加到 list.txt 里
1 2 3 4  下一页
[ 联系联盟系统管理团队 - 中国DOS联盟 - 标准版 ]
Sponsored by ifanr Inc | © 2001–2023