标题: [文件操作] 批处理将文件以数字重命名 [打印本页]
作者: 随风 时间: 2008-6-9 17:13 标题: 批处理将文件以数字重命名
讨论:将文件以数字重命名
看似简单,其实不然。
现有a.txt文件内容如下,一行一个文件名。路径为当前目录。
要求:
1、不能改变a.txt内容的顺序
2、将当前目录下的所有jpg文件以序号的形式重命名 如:从1-16
3、如果有16个文件,必须重命名为1-16,不允许出现16之后的序号
暂不公布我的代码,各位不防先试试。
a.txt 内容:- 2.jpg
- 1.jpg
- a.jpg
- 5ww.jpg
- c.jpg
- f.jpg
- rty.jpg
- 3.jpg
- 11.jpg
- b.jpg
- 6.jpg
- e.jpg
- 8.jpg
- 111.jpg
- 7.jpg
- 30.jpg
复制代码
重新描述一下要求:
当前文件夹有一万多个jpg文件,文件名没有规律,有数字,英文,中文、及中英文混合。
要求:
将jpg文件以数字形式重命名,必须是从1开始递增,即:最大的一个文件名就是文件的总数。
要求效率,即:不能先判断文件的总数,再重命名。
[ 本帖最后由 随风 于 2008-6-10 23:55 编辑 ]
作者: namejm 时间: 2008-6-9 17:36
没有看明白你的意思:是从a.txt中读取jpg文件名来重命名当前目录下的文件?a.txt只是一个单独的文件,如何有顺序一说?
作者: 随风 时间: 2008-6-9 17:46
a.txt中的内容其实就是当前文件夹下的jpg文件列表。
要求将当前文件夹里的所有jpg文件以序号的形式重命名。
但只能从 a.txt 获取当前文件夹里的所有 jpg 的文件名。
以序号重命名文件,陷阱重重,但如果用dir或for等命令来获取文件名的话,获取的先后次序会有一定规律,导致有些问题不能体现出来。
作者: namejm 时间: 2008-6-9 17:56
随风 是担心重命名后文件名可能和现有文件名重名是吧?但是我始终没明白你"不能改变a.txt的顺序
"到底是什么意思:a.txt只是一个单独的文件,没看到它到底和谁排序呢?难道是不能改变a.txt文件内容的顺序?
作者: springcm 时间: 2008-6-9 19:46
不知道以下代码是不是投机:- @echo on
- setlocal enabledelayedexpansion
- set n=0
- set n1=0
- for /f "tokens=*" %%a in (a.txt) do (
- set /a n+=1
- ren %%a t!n!.jpg
- )
- :loop
- set /a n1+=1
- ren t%n1%.jpg %n1%.jpg&&goto :loop
- exit
复制代码
作者: 随风 时间: 2008-6-9 20:37
呵呵,个人认为算投机。。
不过也不错,也是一个解决方法
[ 本帖最后由 随风 于 2008-6-11 16:53 编辑 ]
作者: wankoilz 时间: 2008-6-10 16:55
我有两个版本。第一个:- @echo off
- for /f "delims=" %%i in (a.txt) do set/a n+=1
- for /f "delims=" %%i in (a.txt) do (
- for /l %%j in (1,1,%n%) do if %%~ni equ %%j set .%%j=ok
- )
- for /f "delims=" %%i in (a.txt) do (
- if not defined .%%~ni call :out %%i
- )
- pause
- :out
- for /l %%i in (1,1,%n%) do (if not defined .%%i (ren %1 %%i.jpg&set .%%i=ok&goto :eof))
复制代码
第二个更简单:- @echo off
- for /f "delims=" %%i in (a.txt) do set/a n+=1
- for /f "delims=" %%i in (a.txt) do call :out %%i
- pause
- :out
- for /l %%i in (1,1,%n%) do (ren %1 %%i.jpg 2>nul&&goto :eof)
复制代码
作者: 随风 时间: 2008-6-10 17:15
呵呵,强免完成任务。
两个版本的效率都非常的低。。
..
作者: wankoilz 时间: 2008-6-10 17:21
暂时没想出很简洁的方法,再思考思考..........
作者: wankoilz 时间: 2008-6-10 21:06
再来一个,效率要比前两个要好:- @echo off&setlocal enabledelayedexpansion
- for /f %%i in (a.txt) do (set/a n+=1&set .!n!=ok)
- for /f %%i in (a.txt) do (
- if not defined .%%~ni (set/a n1+=1&set name!n1!=%%i
- ) else (set .%%~ni=)
- )
- for /l %%i in (1,1,%n%) do (if defined .%%i (set/a n2+=1&set num!n2!=%%i))
- for /l %%i in (1,1,%n1%) do ren !name%%i! !num%%i!.jpg
复制代码
作者: 随风 时间: 2008-6-10 21:50
首先:效率仍是问题。
10 楼测试过吗?
代码绕的我好晕。。。
[ 本帖最后由 随风 于 2008-6-10 21:51 编辑 ]
作者: wankoilz 时间: 2008-6-10 23:27
10楼测试过,代码虽然多,但都是for和if,不过也只能说比前面的快点。测试了几次,平均耗时0.03秒。
思路是将a.txt中 范围数字 之外的名称装进一个数组,再将剩余a.txt中没用过的数字装进一个数组,再一一对应重命名。
[ 本帖最后由 wankoilz 于 2008-6-10 23:32 编辑 ]
作者: 随风 时间: 2008-6-10 23:55
见顶楼红色字部分,再试试。。。
作者: wankoilz 时间: 2008-6-11 00:15
测试1000个文件用了2.8秒,10000个不敢测试了。发现太多的set很耗时间........
再思考思考................
[ 本帖最后由 wankoilz 于 2008-6-11 00:32 编辑 ]
作者: lovelymorning 时间: 2008-6-11 16:07
想给想得太简单了,呵呵……
[ 本帖最后由 lovelymorning 于 2008-6-11 16:36 编辑 ]
作者: 随风 时间: 2008-6-11 16:27
呵呵,楼上是想简单了。
假设a.txt内容如下,也就是假设用dir得到的文件名顺序
a.jpg
1.jpg
2.jpg
你执行第一步后,把a.jpg改为1.jpg 就遇到的同名文件。
在你的例子中
ren "2.jpg" "1.jpg"
ren "1.jpg" "2.jpg"
把2改为1 第二句又把1改为了2 结果还是没有1.jpg
作者: wankoilz 时间: 2008-6-12 17:33
仍然没想出更高效率的方法,哪怕是直接ren 10000个文件,都要不少时间吧,难道还有批量命名的什么命令么................
作者: 梦想种子 时间: 2008-6-13 01:13
- @echo off
- setlocal enabledelayedexpansion
- for /f "delims=" %%i in (a.txt) do (
- set /a n+=1
- (ren !n!.jpg _!n!.jpg
- ren _%%i !n!.jpg||(ren %%i !n!.jpg)) 2>nul
- )
复制代码
如果文件名只含有中英数三种字符的话,这样就可以了吧。
作者: 随风 时间: 2008-6-13 02:34 标题: 18 楼
这个问题还真是绕人,看了半天,好像是没问题了。
加分。。。
作者: wankoilz 时间: 2008-6-13 10:57
我也再来一个。效率不如18楼,同样情况下测试2000个文件(1000个是范围内数字,1000个是字母),18楼的平均用3.4秒,我的用4秒半。但如果数字名称的文件很多的话,我的就比较有优势了,呵呵..- @echo off
- for /f %%i in (a.txt) do (set/a max+=1)
- for /f %%i in (a.txt) do (
- call :out %%i
- )
- pause
- :out
- if %1 leq %max% goto :eof
- set /a n+=1
- if exist %n%.jpg (goto :out
- ) else (ren %1 %n%.jpg)
复制代码
[ 本帖最后由 wankoilz 于 2008-6-15 20:18 编辑 ]
作者: 随风 时间: 2008-6-13 13:23
wankoilz 兄弟的钻研精神真是可嘉!
不错,
作者: more 时间: 2008-6-15 12:30
个人认为5楼和18楼实现了改名的操作,但是并不以a.txt的内容作为参考(不合楼主要求),导致了文件名和原文件对不上号,不可取
20楼的代码经测试不成功,而且也不符合不得判断文件总数的要求
期待中...............
作者: 随风 时间: 2008-6-15 13:28 标题: 回22楼
可能我没说清楚,要求是只要把文件按数序号重命名就可以了的,不用管文件名和原文件对不对的上号,所以5楼和18楼应该是可以的。
当然最理想的应该是不需要重命名的文件就不重命名。
比如
a.jpg
5.jpg
2.jpg
c.jpg
其中的2.jpg就不需要重命名。
作者: 梦想种子 时间: 2008-6-15 14:21 标题: 回复 22楼 的帖子
用这个BAT生成JPG:- @echo off
- setlocal enabledelayedexpansion
- set n=0
- del /q *.jpg
- for /f "delims=" %%i in (a.txt) do (
- set /a n+=1
- echo !n!>%%i
- )
- pause
复制代码
这样每个JPG文件内容中都会有一个数字,是按照a.txt中文件名排列的序号。
然后执行重命名的BAT,就可以检查是否对号命名了(若是,改后文件名与该JPG里的数字相同)。
经逐一检查,5楼和18楼的都能严格按照a.txt中的文件名排序对号命名的。
[ 本帖最后由 梦想种子 于 2008-6-15 14:25 编辑 ]
作者: more 时间: 2008-6-15 15:13
原帖由 随风 于 2008-6-15 13:28 发表
可能我没说清楚,要求是只要把文件按数序号重命名就可以了的,不用管文件名和原文件对不对的上号,所以5楼和18楼应该是可以的。
当然最理想的应该是不需要重命名的文件就不重命名。
比如
a.jpg
5.jpg
2.jpg
...
如果是这样的话,我也可以,而且还不会把已经存在的文件(序号小于16的文件)重命名:- @echo off
- for /f "delims=" %%i in (a.txt) do set /a m+=1
- for /f "delims=" %%i in (a.txt) do call :ren_ %%i
- goto :eof
- :ren_
- if %~n1 leq %m% goto :eof
- :again
- set /a n+=1
- if exist %n%.jpg goto :again
- ren %1 %n%.jpg
- goto :eof
复制代码
用这个BAT生成JPG:复制内容到剪贴板代码:
@echo off
setlocal enabledelayedexpansion
set n=0
del /q *.jpg
for /f "delims=" %%i in (a.txt) do (
set /a n+=1
echo !n!>%%i
)
pause这样每个JPG文件内容中都会有一个数字,是按照a.txt中文件名排列的序号。
然后执行重命名的BAT,就可以检查是否对号命名了(若是,改后文件名与该JPG里的数字相同)。
经逐一检查,5楼和18楼的都能严格按照a.txt中的文件名排序对号命名的。
我测试的结果却完全不相同,你真的检查过了吗????????????
[ 本帖最后由 more 于 2008-6-15 15:21 编辑 ]
作者: 梦想种子 时间: 2008-6-15 15:29 标题: 回 25 楼
我测试的结果却完全不相同,你真的检查过了吗????????????
- @echo off
- setlocal enabledelayedexpansion
- for /f "delims=" %%i in ('dir /b *.jpg') do (
- set /p t=<%%i
- set /p=!t! %%~ni <nul
- if !t! == %%~ni (echo Yes) else echo No
- )
- pause
复制代码
本来是手工检查的,没有错。
后来再写了个BAT,检查依然无误...
我环境是WIN XP PRO + SP2
作者: more 时间: 2008-6-15 16:16 标题: 回26楼
我指的是文件里的内容已经改变了,运行以下代码就知道了- @echo off
- setlocal enabledelayedexpansion
- del /f/q *.jpg
- ::按a.txt的内容生成固定内容的.jpg文件(24楼)
- for /f "delims=" %%i in (a.txt) do (
- set /a n+=1
- echo !n!>%%i
- )
- ::显示.jpg文件里的内容,作验证用
- echo 以下为更名前的文件及对应的内容
- for /f "delims=" %%a in ('type a.txt') do (set/p=%%a <nul&type %%a)
- pause
- ::以下为18楼的重命名代码
- echo.&echo 以下为18楼的代码更名后的文件及对应的内容&echo.
- set n=0
- for /f "delims=" %%i in (a.txt) do (
- set /a n+=1
- (ren !n!.jpg _!n!.jpg
- ren _%%i !n!.jpg||(ren %%i !n!.jpg)) 2>nul
- )
- ::以下为验证代码
- for /l %%a in (1 1 16) do (
- set /p=%%a.jpg <nul&type %%a.jpg
- )
- pause
复制代码
作者: more 时间: 2008-6-15 16:28
下面的是我的重命名代码,作一下对比就清楚了:- @echo off
- setlocal enabledelayedexpansion
- del /f/q *.jpg
- ::按a.txt的内容生成固定内容的.jpg文件(24楼)
- for /f "delims=" %%i in (a.txt) do (
- set /a n+=1
- echo !n!>%%i
- )
- ::显示.jpg文件里的内容,作验证用
- echo 以下为更名前的文件及对应的内容
- for /f "delims=" %%a in ('type a.txt') do (set/p=%%a <nul&type %%a)
- set n=0
- echo.&echo 以下为更名后的文件及对应的内容&echo.
- for /f "delims=" %%i in (a.txt) do set /a m+=1
- for /f "delims=" %%i in (a.txt) do call :ren_ %%i
- goto :count_
- :ren_
- if %~n1 leq %m% goto :eof
- :again
- set /a n+=1
- if exist %n%.jpg goto :again
- ren %1 %n%.jpg
- goto :eof
- :count_
- for /l %%a in (1 1 16) do (
- set /p=%%a.jpg <nul&type %%a.jpg
- )
- pause
复制代码
作者: 梦想种子 时间: 2008-6-15 16:32 标题: 回复 27楼 的帖子
我运行的结果是这个:
以下为更名前的文件及对应的内容
2.jpg 1
1.jpg 2
a.jpg 3
5ww.jpg 4
c.jpg 5
f.jpg 6
rty.jpg 7
3.jpg 8
11.jpg 9
b.jpg 10
6.jpg 11
e.jpg 12
8.jpg 13
111.jpg 14
7.jpg 15
30.jpg 16
请按任意键继续. . .
以下为18楼的代码更名后的文件及对应的内容
1.jpg 1
2.jpg 2
3.jpg 3
4.jpg 4
5.jpg 5
6.jpg 6
7.jpg 7
8.jpg 8
9.jpg 9
10.jpg 10
11.jpg 11
12.jpg 12
13.jpg 13
14.jpg 14
15.jpg 15
16.jpg 16
请按任意键继续. . .
证明18楼代码没有问题。
我再把代码换成5楼的,结果还是上面的结果。所以5楼代码没有错。
究竟是怎么回事?有没有第三个人试试?
作者: more 时间: 2008-6-15 16:40 标题: 回29楼
更名前的内容和更名后的内容已经改变啦!
更名前 更名后
1.jpg 2 1
2.jpg 1 2
3.jpg 8 3
............
[ 本帖最后由 more 于 2008-6-15 16:47 编辑 ]
作者: 梦想种子 时间: 2008-6-15 16:55
这肯定要变的啊...
按照a.txt的顺序:
2.jpg 要改成 1.jpg
1.jpg 要改成 2.jpg
a.jpg 要改成 3.jpg
5ww.jpg 要改成 4.jpg
....
注意,原来的2.jpg不同现在的2.jpg了,因为根据a.txt,要改成1.jpg...依此类推
所以,结果就是对的了。不是么?
作者: 随风 时间: 2008-6-15 16:58
好热闹,
我来说两句。
其实我们把a.txt的内容加上行号就可以很好的说明问题了
其实 梦想种子 的意思就是以行号重命名文件,18楼的代码也确实达到如此功效。
而more的意思好像是:
以16个文件为例
若有2.jpg则不能重命名2.jpg ..........
若有10.jpg则不能重命名10.jpg ..........
.....................
个人认为这种思路是最理想的。
作者: more 时间: 2008-6-15 17:17
好热闹,
我来说两句。
其实我们把a.txt的内容加上行号就可以很好的说明问题了
其实 梦想种子 的意思就是以行号重命名文件,18楼的代码也确实达到如此功效。
而more的意思好像是:
以16个文件为例
若有2.jpg则不能重命名2.jpg ..........
若有10.jpg则不能重命名10.jpg ..........
.....................
个人认为这种思路是最理想的。
是的,我以为楼主的原意是这样的(虽然并不是),不过我的代码可达到了这个效果喔.
作者: 随风 时间: 2008-6-15 18:47 标题: 33楼
呵呵。但是你的代码统计了文件总数,同样不合题意啊。
作者: wankoilz 时间: 2008-6-15 20:21
我的有错误,改正了,不过以前的测试文件比较规则,所以可以运行。思路是和more的一样。
作者: more 时间: 2008-6-15 20:22
哈哈,如果没有23楼的回复,我也不会贴出25楼的代码的,所以啊,正如我在22楼所说的,还没有符合题意的代码,依然在期待中........................
作者: 梦想种子 时间: 2008-6-15 21:53
- @echo off
- setlocal enabledelayedexpansion
- for /f "delims=" %%i in (a.txt) do (
- set /a n+=1
- call :check "%%i"
- )
- pause&exit
- :check
- if defined %~n1 (set /a n-=1&goto :eof)
- if exist !n!.jpg (
- set !n!=OK
- set /a n+=1
- goto check
- ) else (
- ren %1 !n!.jpg
- )
复制代码
作者: 随风 时间: 2008-6-15 22:03
哈哈哈哈,37楼 和我的代码一模一样了。
哈哈。。。。
- @echo off
- for /f "delims=" %%a in (a.txt) do call :loop "%%a"
- pause
- :loop
- set /a n+=1
- if exist "%n%.jpg" set .%n%=a&goto loop
- if not defined .%~n1 ren "%~1" "%n%.jpg"&set .%n%=a
- goto :eof
复制代码
作者: 梦想种子 时间: 2008-6-15 22:49 标题: 回复 38楼 的帖子
你逻辑顺序比较好,所以简短很多。
作者: more 时间: 2008-6-15 23:27
经测试37楼成功,38楼不成功,原因如下:
这是a.txt的部分内容:
2.jpg
1.jpg
a.jpg
5ww.jpg
c.jpg
当call :loop 2.jpg;当n加到4的时候出错,
if exist "4.jpg" set .4=a&goto loop ==>这句不执行
if not defined .2 ren "%~1" "4.jpg"&set .4=a ==>这句也不执行
goto :eof ==>一直未定义.4
所以出错
作者: 随风 时间: 2008-6-15 23:38
是啊,漏了一句。else set /a n-=1
:- @echo off
- for /f "delims=" %%a in (a.txt) do call :loop "%%a"
- pause
- :loop
- set /a n+=1
- if exist "%n%.jpg" set .%n%=a&goto loop
- if not defined .%~n1 (ren "%~1" "%n%.jpg"&set .%n%=a) else set /a n-=1
- goto :eof
复制代码
欢迎光临 批处理之家 (http://www.bathome.net/) |
Powered by Discuz! 7.2 |