@ECHO OFF
SETLOCAL
SET "relroot=u:\photos collection 01"
SET "oldmask=im age"
SET "newmask=new name"
SET "ext=jpg"
SET "skipped="
::
:: step 1 - ensure no 'newname*.ext' exists in the subtree
::
FOR /f %%i IN (
'DIR /s/b/a-d "%relroot%\%newmask%*.%ext%" 2^>nul^|FIND /c /v "" '
) DO IF NOT %%i==0 ECHO Files matching new mask already exist&GOTO :EOF
::
:: step 2 - list target files
::
:temploop
SET tempfile=%temp%\Photo%random%
IF EXIST "%tempfile%*" GOTO temploop
:: now have random tempfile name
(
FOR /f "delims=" %%i IN (
'DIR /s/b/a-d "%relroot%\%oldmask%*.%ext%" '
) DO (
ECHO %%~ni*%%~fi
)
)>"%tempfile%1"
::
:: Now do the rename
::
SET count=1000
SET prev=%newmask%
FOR /f %%i IN ('find /c "*" ^<"%tempfile%1"') DO IF %%i gtr 1000 ECHO %%i files - exceeds capacity&GOTO :eof
FOR /f "delims=*" %%i IN ('SORT "%tempfile%1"') DO (CALL :incren "%%i")
IF DEFINED skipped ECHO some files were NOT renamed&DIR /s/b/a-d "%relroot%\%oldmask%*.%ext%"
DEL "%tempfile%1"
GOTO :eof
:incren
:: repeat?
IF "%prev%"==%1 GOTO :EOF
:: no - process next name found
SET "prev=%~1"
FOR %%n IN (firstname secondname) DO (SET %%n=)
:: scan the tempfile, looking for matches to name found
FOR /f "usebackqtokens=1,2delims=*" %%m IN ("%tempfile%1") DO IF /i "%%m"=="%prev%" (
IF DEFINED firstname SET skipped=Y&IF NOT DEFINED secondname SET secondname=%%n
IF NOT DEFINED firstname SET firstname=%%n
)
IF DEFINED secondname SET firstname=%secondname%
ECHO REN "%firstname%" "%newmask%%count:~-3%.%ext%"
SET /a count+=1
GOTO :eof
好吧,毕竟不是太难。
不太符合你的规范 - 我不想删除文件,所以我mereley没有重命名重名的任何目标。
试图处理愚蠢的文件名海事组织过于关注。如果你在你的文件名中使用了!%^)=
这样的字符 - 那么你非常聪明 - 你会发现它。
因此,假设合理的文件名字符和空格,工作!
首先设置您的relative root
(起始子目录)名称,要使用的文件掩码,旧的和新的以及扩展名。我使用set "var=string"
语法来避免应用杂乱的终端空间,这些空间是不可见的并且可能导致混乱。还要注意,在一个字符串赋值中,'='两边的空格是重要的。
第一步是记录。如果在树中已经有与新名称匹配的文件,不知道该怎么做 - 所以不要做任何事情。从dir /s/b/a-d
(包含子目录,基本表单(因此不包含标题)和目录名称)目录中出现的行数应该为0,如果一切正常。
我喜欢用showm方法设置tempfiles。如果%temp%
中没有与选择的随机名匹配的名称,那么使用该名称+您喜欢的任何附录应该是安全的(如果需要,可以创建许多临时文件)。
下一步是获取子目录再次使用基本形式的旧名称文件 - 但是这次输出到tempfile。什么是输出是每个文件的一行,只有名称部分(%%~ni
)以星号和完整文件名(%%~fi
)结构。星号充当列分隔符并且安全,因为*
不能出现在文件名中。
接下来是重命名阶段。我们在1000处开始COUNT
,以便我们可以使用最后3个字符来创建名称。你想从001开始,只需要使用1001。 PREV
被初始化为一个不能显示为要重命名的文件名的值。
再次,计算要重命名的名称。如果太多,放弃船舶。
下一步是对tempfile进行排序,因此结果将按照原始base-filename(在每行中的“*”之前)进行处理,然后如果名称匹配,按照子目录名称的字母顺序(因为name * parent会在name * parent \ subdir之前排序)。遇到的每个名称然后传递到:incren
例程 - 引用以适应文件名空间要求。
INCREN例程所做的第一件事是检查名称是否重复遇到的以前的名称。如果是这样,名称将被忽略(因为它已经被处理)。然后将PREV
设置为遇到的下一个名称。 SET "prev=%~1"
去除第一个参数报价,那么结果firstname
分配给prev
和封闭引号防止杂散空间从碰撞。和secondname
,然后设置为[无]
然后,我们再次扫描临时文件,找了匹配名称作为第一个标记并将第二个标记(全文件名)分配给%%n
当第一个找到时,firstname没有设置,因此将其设置为完整文件名。 如果找到第二个名字,则firstname
将已设置,因此请设置SKIPPED
来标记已遇到问题。如果第二个文件名尚未设置,则将secondname
设置为即全文件名 应该进一步匹配找到,那么因为现在设置了secondname
,所以不会做任何进一步的处理。
处理完文件后,我们将firstname
设置为第一个完整文件名(因为相对根是第一个遇到的),并且secondname
仅在找到两个或更多匹配名称时才会设置。在这种情况下,将firstname
设置为遇到的第二个名称的值,该名称将位于较低的子目录中。
现在做RENAME。我只是ECHO
编辑它,但要激活,从ECHO REN...
线删除ECHO
。我们知道firstname
包含要重命名的文件的全名,并且我们知道新文件名的结构将成为新的掩码+ COUNT
的最后3个字符+一个点+所选扩展名。
并撞上计数准备下一次重命名...
这是一个测试运行与ECHO
删除:
============= before =========
u:\photos collection 01\im age 612.jpg
u:\photos collection 01\im age 003.jpg
u:\photos collection 01\im age 005.jpg
u:\photos collection 01\im age 610.jpg
u:\photos collection 01\im age 009.jpg
u:\photos collection 01\im age 609.jpg
u:\photos collection 01\im age 505.jpg
u:\photos collection 01\selection 01\im age 001.jpg
u:\photos collection 01\selection 01\im age 004.jpg
u:\photos collection 01\selection 01\im age 005.jpg
u:\photos collection 01\selection 01\im age 006.jpg
============= run =========
some files were NOT renamed
u:\photos collection 01\im age 005.jpg
============= after =========
u:\photos collection 01\new name009.jpg
u:\photos collection 01\new name001.jpg
u:\photos collection 01\im age 005.jpg
u:\photos collection 01\new name008.jpg
u:\photos collection 01\new name005.jpg
u:\photos collection 01\new name007.jpg
u:\photos collection 01\new name006.jpg
u:\photos collection 01\selection 01\new name000.jpg
u:\photos collection 01\selection 01\new name002.jpg
u:\photos collection 01\selection 01\new name003.jpg
u:\photos collection 01\selection 01\new name004.jpg
注意这是agains FAT驱动器执行,因此实际文件的顺序是两个清单相同。
我不相信,有任何理智的方法来实现4)使用批处理文件。为此你需要一些真正的编程语言。如果您想保持接近脚本,请考虑PowerShell或VBScript/JScript。 –