中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net 论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

中国DOS联盟论坛
现在时间是 2026-06-22 04:33
中国DOS联盟论坛 » DOS批处理 & 脚本技术(批处理室) » 一个关于随机获取文件名的问题. 精华I 查看 17,407 回复 54
16 发表于 2006-07-27 20:38 ·  中国 广西 玉林 博白县 电信
金牌会员
★★★★
积分 3,687
发帖 1,467
注册 2005-08-08 12:00
20年会员
UID 44210
状态 离线
重新编了一个,不用文本查询,清除写入过列表的变量来判断循环生成随机数
137个文件30秒内完成(随机数运气好的话速度就快,越往后有效变量越少越慢):
红色部分不要

pause
cls
@echo off
copy nul List.txt >NUL
setlocal EnableDelayedExpansion
for /f "delims=" %%a in ('dir/b *.mp3^|find ".mp3"') do (
set /a N=!N! + 1
set Name!N!=%%a)

echo.
echo 随机生成列表,请稍等...
echo.
echo 序号 - 随机文件名
echo.
:loop
set N=%random:~-3%
if "%N%" == "000" goto loop
if "%N:~0,1%" == "0" set N=%N:~1%
if "%N:~0,1%" == "0" set N=%N:~1%
if %N% GTR 137 goto loop“137”文件数量
echo set Name=%%Name!N!%%>Temp.bat判断改变量是否被清除
call Temp.bat
if "%Name%" == "" goto loop

set /a M=%M%+1
echo echo %%M%% - %%Name!N!%%>Temp.bat显示序号 - 随机文件名
echo echo %%Name!N!%%^>^>List.txt>>Temp.bat
call Temp.bat
set Name!N!=清除已写入列表的变量
if %M% GEQ 137 goto End“137”文件数量
goto loop

:End
del Temp.bat
echo.
echo 完成!
echo.
pause
exit


好像有个小毛病:有时候会失败退出:(

[ Last edited by zxcv on 2006-7-28 at 01:19 ]
17 发表于 2006-07-27 20:57 ·  中国 广西 玉林 博白县 电信
金牌会员
★★★★
积分 3,687
发帖 1,467
注册 2005-08-08 12:00
20年会员
UID 44210
状态 离线
来一个自动判断文件数量设置随机位数的:
@echo off
pause
cls

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 /a N=!N! + 1
set Name!N!=%%a)

echo.
echo 随机生成列表,请稍等...
echo.
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
echo echo set Name=%%%%Name%%N%%%%%%^>Temp.bat>>Loop.bat
echo call Temp.bat>>Loop.bat
echo if "%%Name%%" == "" goto loop>>Loop.bat

:loop
call Loop.bat
set /a M=!M!+1
echo echo %%M%% - %%Name!N!%%>Temp.bat
echo echo %%Name!N!%%^>^>List.txt>>Temp.bat
call Temp.bat
set Name!N!=
if %M% GEQ %文件数量% goto :End
goto loop

:End
del Loop.bat
del Temp.bat
echo.
echo 完成!
echo.
pause
exit
18 发表于 2006-07-27 21:44 ·  中国 广东 中山 广东瑞江科技有限公司BGP数据中心
中级用户
★★
积分 384
发帖 189
注册 2005-10-19 13:12
20年会员
UID 43709
性别 男
状态 离线
有这么多朋友的代码相信已经足够矣...

我拿下来慢慢研究一下,希望能拼凑个更快更有效率的出来...^_^

谢谢各位...
19 发表于 2006-07-27 22:20 ·  中国 辽宁 葫芦岛 中移铁通
荣誉版主
★★★
积分 1,338
发帖 356
注册 2005-07-15 12:09
20年会员
UID 40733
性别 男
状态 离线
Re voiL
在我这里每次的执行结果都不是一样的,并且没有文件名前的"编号"。麻烦贴一下结果我看看。
  ☆开始\运行 (WIN+R)☆
%ComSpec% /cset,=何奈无── 。何奈可无是原,事奈无做人奈无&for,/l,%i,in,(22,-1,0)do,@call,set/p= %,:~%i,1%<nul&ping/n 1 127.1>nul

20 发表于 2006-07-27 22:42 ·  中国 广西 玉林 博白县 电信
金牌会员
★★★★
积分 3,687
发帖 1,467
注册 2005-08-08 12:00
20年会员
UID 44210
状态 离线
无奈何版主的不错,速度也快
不过有空格的文件名断了(不完整)应该可以些改一下
21 发表于 2006-07-27 23:00 ·  中国 四川 成都 鹏博士宽带
荣誉版主
★★★★
batch fan
积分 5,226
发帖 1,737
注册 2006-03-10 00:38
20年会员
UID 51697
来自 成都
状态 离线
Originally posted by doscc at 2006-7-27 20:38:
我的代码 应该不会出现重复的行
因为在下面这一行做了过虑
echo %y% | findstr /r "\<%r%\>" >NUL || set y=%y% %r% & call :ls %r%
y 记录每个不一样的 随机数
当 r 不在 y 中出现时 就 记录 r 并 调用 :ls 把 tem.txt 中的第 r 行 追加到 list.txt 里


  大概弄明白了你的过滤规则。

  你在16楼的代码有问题,不知道红字部分是注释还是代码;如果是代码的话,执行完毕之后,list.txt文件里会有为数众多的行内容为“ 清除已写入列表的变量”;如果是注释的话,把注释部分清除掉之后,list.txt中为数众多的行内容为"ECHO 处于关闭状态。"

  你说这段代码有时候会失败退出,估计是要处理的行数太多,导致name!N!变量太多,而CMD中变量的数量好象是有限制的。

[ Last edited by namejm on 2006-7-28 at 09:13 ]
尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。
22 发表于 2006-07-27 23:09 ·  中国 四川 成都 鹏博士宽带
荣誉版主
★★★★
batch fan
积分 5,226
发帖 1,737
注册 2006-03-10 00:38
20年会员
UID 51697
来自 成都
状态 离线
Originally posted by zxcv at 2006-7-27 22:42:
无奈何版主的不错,速度也快
不过有空格的文件名断了(不完整)应该可以些改一下


  无奈何版主的代码,除了9楼有一处之外,在什么地方还有哦?也想拿来跑一下。
尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。
23 发表于 2006-07-27 23:40 ·  中国 北京 海淀区 IDC机房
中级用户
★★
积分 256
发帖 93
注册 2006-03-26 22:12
20年会员
UID 52853
性别 男
来自 广东
状态 离线
Originally posted by namejm at 2006-7-27 23:00:


  大概弄明白了你的过滤规则。

  你在16楼的代码有问题,不知道红字部分是注释还是代码;如果是代码的话,执行完毕之后,list.txt文件里会有为数众多的行内容为“ 清除已写入列表的变量”;如果是注释的话,list.txt中为数众多的行内容为"ECHO 处于关闭状态。"

  你说这段代码有时候会失败退出,估计是要处理的行数太多,导致name!N!变量太多,而CMD中变量的数量好象是有限制的。你在16楼的代码有问题,不知道红字部分是注释还是代码;如果是代码的话,执行完毕之后,list.txt文件釠...

16 楼是 zxcv 兄的代码.

11楼 则是我的代码. 以作更新!
24 发表于 2006-07-27 23:51 ·  中国 辽宁 葫芦岛 中移铁通
荣誉版主
★★★
积分 1,338
发帖 356
注册 2005-07-15 12:09
20年会员
UID 40733
性别 男
状态 离线
Re zxcv
谢谢指正,含空格的文件名确实有问题,简单修正一下。
Re namejm
请见本楼修正代码。


  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 "delims=" %%i in ('dir /b /a-d') do @call :sub %%i
  5. goto :EOF
  6. :sub
  7. echo %random%:%*
  8. goto :EOF
无奈何发表于 2006-07-27 23:44
  ☆开始\运行 (WIN+R)☆
%ComSpec% /cset,=何奈无── 。何奈可无是原,事奈无做人奈无&for,/l,%i,in,(22,-1,0)do,@call,set/p= %,:~%i,1%<nul&ping/n 1 127.1>nul

25 发表于 2006-07-28 00:00 ·  中国 广西 玉林 博白县 电信
金牌会员
★★★★
积分 3,687
发帖 1,467
注册 2005-08-08 12:00
20年会员
UID 44210
状态 离线
无奈何版主代码的速度很快,137个文件只用了不到3秒
@echo off
copy nul List.txt >NUL

if "%1" NEQ "$" (

for /f "tokens=1,2 delims=:" %%a in ('"%~0" $^|sort') do @echo %%b>>List.txt

) else for /f "delims=" %%i in ('dir /b /a-d *.mp3') do @call :sub %%i

goto :EOF

:sub

echo %random%:%*

goto :EOF


[ Last edited by zxcv on 2006-7-28 at 00:02 ]
26 发表于 2006-07-28 00:50 ·  中国 四川 成都 鹏博士宽带
荣誉版主
★★★★
batch fan
积分 5,226
发帖 1,737
注册 2006-03-10 00:38
20年会员
UID 51697
来自 成都
状态 离线
Re doscc:

  sorry,把你的代码看错了,不好意思。
尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。
27 发表于 2006-07-28 01:11 ·  中国 广西 玉林 博白县 电信
金牌会员
★★★★
积分 3,687
发帖 1,467
注册 2005-08-08 12:00
20年会员
UID 44210
状态 离线
Originally posted by namejm at 2006-7-27 23:00:


  大概弄明白了你的过滤规则。

  你在16楼的代码有问题,不知道红字部分是注释还是代码;如果是代码的话,执行完毕之后,list.txt文件釠...

后面文字为注悉,BAT里面不要

name!N!变量我试过548都没问题,估计是
echo set Name=%%Name!N!%%>Temp.bat
call Temp.bat
这部分有时候来不及反应

[ Last edited by zxcv on 2006-7-28 at 01:18 ]
28 发表于 2006-07-28 09:12 ·  中国 四川 成都 鹏博士宽带
荣誉版主
★★★★
batch fan
积分 5,226
发帖 1,737
注册 2006-03-10 00:38
20年会员
UID 51697
来自 成都
状态 离线
Re zxcv:

  如果你红色部分为注释的话,这样的注释格式是错误的,有的地方还会引起执行错误,比如 set Name!N!=清除已写入列表的变量 这一句,会把"清除已写入列表的变量"这个值赋给Name!N!这个变量,希望你能修正。
尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。
29 发表于 2006-07-28 09:25 ·  中国 四川 成都 鹏博士宽带
荣誉版主
★★★★
batch fan
积分 5,226
发帖 1,737
注册 2006-03-10 00:38
20年会员
UID 51697
来自 成都
状态 离线
  无奈何版主25楼的代码写得简洁至极,同时也让人费解至极,看了老半天,还是云里雾里的,难道真的像他以前所声称的那样,代码要写得尽量简洁、尽量晦涩?如果只是简洁,那可是我等的福气;如果再加上“尽量晦涩难懂”,我的妈呀,估计要晕倒一片像我这样的菜菜。希望无奈何版主能把你的代码稍微点拨一下,以便让我们对你的思路有所了解,光有9楼的只言片语我觉得还不过瘾。

  发现了一个有趣的现象:如果把24楼代码打头的那句@echo off去掉,list.txt的内容将会大大增加,增加的内容形如"\当前文件夹名>echo 20454",一般而言,如果文件有N个,这样的内容也回增加N行,按理说@echo off语句只是起屏蔽回显的作用,但是在这段代码中竟然会影响执行结果,有点匪夷所思。顺便提一下,代码中的@echo %%b>>List.txt和@call :sub %%i中的@去掉之后似乎并不影响代码执行时候的表现,不知道无奈何版主为何还要保留@。

[ Last edited by namejm on 2006-7-28 at 10:59 ]
尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。
30 发表于 2006-07-28 09:42 ·  中国 广西 玉林 博白县 电信
金牌会员
★★★★
积分 3,687
发帖 1,467
注册 2005-08-08 12:00
20年会员
UID 44210
状态 离线
Originally posted by namejm at 2006-7-28 09:12:
Re zxcv:

  如果你红色部分为注释的话,这样的注释格式是错误的,有的地方还会引起执行错误,比如 set Name!N!=清除已写入列表的变量 这一句,会栮..

说实话,那是我说明本行的作用发贴时加上去的,真正的BAT中本来就没有(所以我的说明:红色部分不要);不过你应该可以看得懂那些是不要的啊

俺不太清楚怎样在后面加上不影响代码的注悉
论坛跳转: