![]() |
中国DOS联盟-- 联合DOS 推动DOS 发展DOS --联盟域名:www.cn-dos.net 论坛域名:www.cn-dos.net/forum |
| 游客 | 登录 | 注册 | 会员 | 搜索 | 中国DOS联盟 |
|
中国DOS联盟论坛 现在时间是 2026-09-15 12:22 |
共 47,812 主题排行 / 349,917 发帖 / 今日 0 篇 / 48,268 会员排行 |
| DOS批处理 & 脚本技术(批处理室) » 已结:[转帖求助]一个批量命名的批处理 |
| 可打印版本 3,796 / 12 |
| 第1楼 chenhui530 | 发表于 2005-12-05 23:19 |
| 高级用户 发帖 273 积分 772 | |
|
已结:[转帖求助]一个批量命名的批处理 昨晚我在中国电脑俱乐部看到了一个和批处理有关的问题
作者的原话如下: 求一个关于文件批量改名简单的程序(在线等) 情况是这样的:我现在工作需要处理些图片,把图片分类放在许多文件夹里,然后在把每个文件夹里的图片加序号改名,比如一个文件夹名字为AAA111,里面有3个图片,就要把这3图片名字改为AAA111-01,AAA111-02,AAA111-03.我想大致就是把文件名提取,然后在.......真后悔读书的时候没好好掌握一门语言,哎~ 前些天图片数量少,我用个更名软件还能应付,最近每天4,5千张,实在是弄不了了,路过的朋友帮帮忙撒.我QQ7885347 当时我也想用批处理解决但是一下想不到怎么提取目录名 就用VBS写了一个 代码如下: Const ForReading = 1, ForWriting = 2, ForAppending = 8 Const TristateUseDefault = -2, TristateTrue = -1, TristateFalse = 0 const WindowsFolder=0,SystemFolder=1,TemporaryFolder=2 Set fs = CreateObject("Scripting.FileSystemObject") Set ws = CreateObject("Wscript.Shell") set sys = fs.GetSpecialFolder(SystemFolder) sum = 0 call input() private sub input() dim str str=InputBox( "请输入你要搜索的路径,程序" & vbnewline & "会搜索指定路径的所有子路径","目标目录") if str <> "" then if fs.FolderExists(str) then call search(str) else Msgbox "请输入正确的路径",0,"提示" call input end if else if msgbox(" 您确定退出本程序吗?",4,"提示")=vbyes then wscript.quit call input end if end sub Function search(path1) dim f1,f2,subfolder,path2,path2file,path2files,renname,foldername,appfile,appfiles,i,j,appfilename,appfilesname if right(path1,1) <> "\" then path1 = path1 & "\" Set f = fs.GetFolder(path1) set appfiles = f.files for each appfile in appfiles appfilename = path1 & appfile.name For j = Len(f) To 1 Step -1 '这里至关重要 If InStr("\", Mid(f, j, 1)) Then Exit For Next appfilesname = Mid(f, j + 1, Len(f) - j) '分离出目录名 if Lcase(fs.GetExtensionName(appfilename)) = "jpg" or Lcase(fs.GetExtensionName(appfilename)) = "bmp" then ws.run "cmd /c ren " & appfilename & " " & appfilesname & fs.GetBaseName(appfilename) & "-" & sum & "." & fs.GetExtensionName(appfilename),0,true sum = sum + 1 end if next sum = 0 Set sf = f.SubFolders For Each f1 in sf f2 = path1 & f1.name & "\" set path2 = fs.getfolder(f2) set path2file = path2.files for each path2files in path2file renname = f2 & path2files.name foldername = fs.GetParentFolderName(renname) For i = Len(foldername) To 1 Step -1 If InStr("\", Mid(foldername, i, 1)) Then Exit For Next foldername = Mid(foldername, i + 1, Len(foldername) - i) if Lcase(fs.GetExtensionName(renname)) = "jpg" or Lcase(fs.GetExtensionName(renname)) = "bmp" then ws.run "cmd /c ren " & renname & " " & foldername & fs.GetBaseName(renname) & "-" & sum & "." & fs.GetExtensionName(renname),0,true sum = sum + 1 end if next sum = 0 search(f2) next End Function msgbox "完成操作",0,"提示" 谁能给出批处理代码: [ Last edited by willsort on 2005-12-9 at 16:09 ] |
|
| 第2楼 bush | 发表于 2005-12-05 23:34 |
| 银牌会员 发帖 730 积分 2,165 | |
|
提个思路: dir/a:d /b 〉定向到列表文件
然后再用作批处理参数…… |
|
| 第3楼 无奈何 | 发表于 2005-12-06 11:46 |
| 荣誉版主 发帖 356 积分 1,338 | |
|
用 Total Commander 很方便的,命名规则处填 [P][C] 就完事了。当然用批处理也不是不可完成,但是确实有这个必要吗?
提取目录名可以试试 for /r %i in (.) do @echo %~ni |
|
| 第4楼 chenhui530 | 发表于 2005-12-06 16:04 |
| 高级用户 发帖 273 积分 772 | |
Originally posted by bush at 2005-12-5 11:34 PM: 有必要啊~ 使用批处理简单方便些 只是对于SUM的递加和换了目录又重新开始递加不是那么好实现吧 |
|
| 第5楼 无奈何 | 发表于 2005-12-06 17:19 |
| 荣誉版主 发帖 356 积分 1,338 | |
|
我仍然认为专业的重命名和文件管理软件来做这件事最合适,而用批处理完成这个任务对于批处理不熟悉的人来说无疑增加使用难度。
既然有必要就给你写一个,只作为技术讨论。 我没有做细节处理,命名格式为 3 位数字,默认只重命名 jpg 文件,漠视重命名失败。有必要自行添加修改。 |
|
| 第6楼 chenhui530 | 发表于 2005-12-06 19:33 |
| 高级用户 发帖 273 积分 772 | |
|
确实高明~~
|
|
| 第7楼 willsort | 发表于 2005-12-07 21:08 |
| 元老会员 发帖 1,512 积分 4,432 | |
|
Re 无奈何:
没有实际测试这段代码,仅仅纸上谈兵提几点建议: 1、可否在 for /f 中加上文件的路径,以避免 pushd/popd 的使用? 2、可否将 for /f 改为 for %%a in (files) 的形式? 3、可否使用 setlocal 启动变量延迟,以避免 call :rname? 4、如果需要使用 call ,那么可否不用传递变量n,而在 :rname 中直接引用? |
|
| 第8楼 无奈何 | 发表于 2005-12-08 13:50 |
| 荣誉版主 发帖 356 积分 1,338 | |
|
for /f "delims=" %%a in ('dir /b *.jpg 2^>nul') do (
to willsort 兄的几点建议真是点点击中要害,实在是比我高明多了。由于写批程序时总是不自觉的向曾经写过的程序片段靠拢,哪怕是有更简洁处理方式也想不到了,看来习惯思维太绊脚了。关于第二点 for /f 也有一点好处,就是可以利用其后 dir /o 参数来定义文件重命名顺序,来增强应用的灵活性,只是在本例无此要求,所以也就无意义了。 修改一下,缩水不少。
上面的是原贴内容,本来已经完结,zreo 发现有问题并通知了我,居然存在严重 bug 。我仔细研究了一下找到了原因,这同时也是一个有趣的问题,所以我不直接修改原程序了,简单叙述一下这个问题。 请注意一下上面代码红色的部分,我本想省去 for /f 繁琐的命令输出解析,而直接用 for 获取文件名。但这就成了问题的根源,for %%a ... 会获取已经重命名后的文件而再次命名,文件数量多时会造成一直重命名的死循环。所以仍旧采用原先的处理方式,修正如下:
[ Last edited by 无奈何 on 2005-12-12 at 21:59 ] |
|
| 第9楼 无奈何 | 发表于 2005-12-12 02:03 |
| 荣誉版主 发帖 356 积分 1,338 | |
|
to zreo
你的问题让我发现一个重大 bug ,已经修正了。 |
|
| 第10楼 zreo | 发表于 2005-12-12 11:24 |
| 初级用户 发帖 14 积分 51 | |
|
for /F "delims=" %a in ('dir /b *.jpg 2>nul')
这个得不到答案,而且还不能给文件重命名,用了一个得出来的结果是这样的。 I:\>( 在我的机上试了一下,%a得不到文件参数,这样就不能给文件重命名了 echo on 加了一个pushd "%%i"就得到值了。可以解释一下吗? [ Last edited by zreo on 2005-12-12 at 11:38 ] |
|
| 第11楼 无奈何 | 发表于 2005-12-12 11:37 |
| 荣誉版主 发帖 356 积分 1,338 | |
|
to zreo
在批处理文件中要用 %% 替换 % 。 |
|
| 第12楼 zreo | 发表于 2005-12-12 11:40 |
| 初级用户 发帖 14 积分 51 | |
|
我在批处理中是用双%%号的,可是%a还是得不到参数,反面加了一句
pushd "%%i" 就可以得到相要的了。 |
|
| 第13楼 无奈何 | 发表于 2005-12-12 14:04 |
| 荣誉版主 发帖 356 积分 1,338 | |
|
pushd "%%i" 更改了当前路径,然后对当前目录下文件进行更名。
可以用全路径,省去这条语句,我又改了一下。 |
|
|
[ 联系联盟系统管理团队 -
中国DOS联盟 -
标准版 ] Sponsored by ifanr Inc | © 2001–2023 |