批量重命名为带前导零的数字名称

Batch rename to numeric names with leading zeroes

所以我正在尝试编写一个批处理,将 <randomname>.EPL 重命名为 fbXYZ.EPL(XYZ - 带前导零的数字)

所以像 bes_rush.EPL 这样的东西应该变成 fb001.EPL 并且其他文件也应该重命名(fb002.EPLfb003.EPL 等)

这是我目前所拥有的

setlocal ENABLEDELAYEDEXPANSION
set/a fileNum = 0
set fileNum=0000%fileNum%
set fileNum=%fileNum:~-3%

for %%f in (*.EPL) do (
  ren %%~nf%%~xf fb!fileNum!%%~xf
  set/a fileNum += 1
)

我可以用数字重命名它,它确实有效,但我根本无法添加前导零, 我所有的尝试都导致它只重命名一个文件并保留其余文件

以下是我的建议:

但是请注意,该示例不适合目录中任何已匹配 fb<num><num><num>.EPL 的现有文件名,因此这些文件名也将使用可能的新编号重命名。

@Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
Set "SourceDir=."
Set "FileGlob=*.EPL"
Set "Prefix=fb"
Set "FileNum=1000"
For /F Delims^= %%G In ('(Set PATHEXT^=^) ^& "%SystemRoot%\System32\where.exe"
 /F "%SourceDir%":"%FileGlob%" 2^> NUL') Do (Set /A FileNum += 1
    SetLocal EnableDelayedExpansion & Ren %%G "%Prefix%!FileNum:~-3!%%~xG"
    EndLocal)
  • = 和关闭 "3 之间插入所需的源目录,(我使用 . 作为当前目录,根据您的示例,但您可以根据需要使用绝对路径或其他相对路径).
  • = 和结束 "4 之间插入所需的文件 glob 前缀字符串,(我使用 *.EPL匹配你的例子).
  • = 和结束 "5 之间插入所需的文件名前缀字符串,(我使用 fb匹配你的例子).

我使用 1000 作为您的起始文件编号,因为 Set /A 使用整数,并且将多个并发的 0 视为 0。添加 1 将防止这种情况发生,并且在变量扩展时将被省略,仅使用最后三个字符。我还对其进行了调整,以便文件编号以 fb001.EPL 开头,以匹配您的问题参数,(您的代码以 fb000.EPL 开始序列).

我在循环中启用了延迟扩展,因为在同一个带括号的代码块中修改和使用变量时需要这样做。通常不应为整个脚本启用它,因为包含 ! 个字符的文件名和字符串会受到影响,(这些字符将被省略).

我还使用 where.exe 选择了文件 'belt and braces'。此实用程序不受使用 8.3 命名的 Windows 的影响,虽然它可能不是您提供的示例 的问题,但它将完全匹配扩展名 .EPL,而不是以 .EPL 开头的那些。标准 For 循环、(您使用的) 和更常用的 Dir 命令均受 8.3 命名的影响。

为了更加稳健,我使用了 where.exe 的完整路径和系统环境变量 %SystemRoot%,以防止依赖经常被破坏的 %Path% 变量,通过它不正确或意外的最终用户修改。


作为对您自己的代码的直接解析,无需修改大部分代码:

setlocal ENABLEDELAYEDEXPANSION
set /a fileNum = 1
set fileNum=1000%fileNum%

for %%f in (*.EPL) do (
  ren "%%f" fb!fileNum:~-3!%%~xf
  set /a fileNum += 1
)

不过我必须补充一点,那是因为您的示例代码使用的是标准 for 循环,您可能会遇到问题。问题是你的循环会将第一个文件传递给 do 部分,同时它仍在解析包含所有内容的 * glob 下的其他文件。这意味着 fb001.EPL 将被放回列表中进行解析,并且可以再次拾取以进行下一次处理,这也可以继续用于其他文件!

@ECHO Off
SETLOCAL ENABLEDELAYEDEXPANSION
rem The following settings for the source directory, destination directory, target directory,
rem batch directory, filenames, output filename and temporary filename [if shown] are names
rem that I use for testing and deliberately include names which include spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.

SET "sourcedir=u:\your files\t w o"
SET /a filenumber=1001

FOR /f "delims=" %%b IN ('dir /b /a-d "%sourcedir%\*.epl" ' ) DO (
 SET "originalfilename=%%~nb"
 SET "notnumber=Y"
 rem do not rename files "fb999"
 IF /i "!originalfilename:~0,2!!originalfilename:~5!" == "fb" IF "!originalfilename:~4!" neq "" CALL :isnum !originalfilename:~2,3!
 IF defined notnumber (
  CALL :nextvalidnum
  IF NOT DEFINED filenumber ECHO Fail - no available fb999&GOTO :EOF 
  REN "%sourcedir%\%%b" "fb!filenumber:~-3!.epl"
 )
)
GOTO :EOF

:: Determine whether %1 is purely numeric
:isnum
SET "notnumber=9%1"
FOR /l %%z IN (0,1,9) DO CALL SET "notnumber=%%notnumber:%%z=%%"
GOTO :eof

:: set filenumber to next valid fb(1)999 or empty if not available
:nextvalidnum
IF %filenumber% gtr 1999 SET "filenumber="&GOTO :EOF 
IF EXIST "%sourcedir%\fb%filenumber:~-3%.epl" SET /a filenumber+=1&GOTO nextvalidnum
IF %filenumber% gtr 1999 SET "filenumber="
GOTO :eof

最初将 filenumber 设置为 1001,期望使用最后 4 个字符作为新的 fb999 名称。

读取每个 .epl 名称,仅处理那些 而不是 名为 fb999 的文件。这是通过记住字符串中的第一个字符是“字符 0”来完成的;检测到名称的前 2 个字符是 fb,没有超过第五个字符的字符,文件名中的第四个字符存在并且从字符 2 开始的三个字符都是数字。如果作为 %1 提供的值是全数字,则例程“isnum”将 notnumber 设置为 undefined,否则设置为 defined

如果定义了notnumber,文件名将被处理。如果文件 fb+last 3 characters of "filenumber".epl 存在,则通过递增 filenumber 来检测下一个有效数字。如果 filenumber 超过 1999 则没有可用号码。如此清楚 filenumber 并将其用作显示消息并退出的标志。