这是一个批处理文件解决方案。批处理文件应保存在包含该目录或其子目录中所有 *.mp3 文件的目录中,并通过双击执行。
@echo off
for /F "eol=| delims=" %%I in ('dir "* *.mp3" /A-D /B /S 2^>nul') do call :RenameFile "%%I"
set "NewName="
pause
goto :EOF
:RenameFile
set "NewName=%~nx1"
set "NewName=%NewName: = - %"
ren "%~1" "%NewName%"
goto :EOF
命令DIR搜索
- 仅用于文件,因为
/A-D(不是属性目录)
- 在当前目录和所有子目录中因为
/S
- 对于包含 3 个连续空格的 *.mp3 文件和
- 由于
/B 找到的文件的名称带有文件扩展名和完整路径,因此以裸格式输出。
DIR 命令行由 FOR 在后台的单独命令进程中执行,该命令进程捕获此命令进程的输出(= command DIR) 编写用于处理 STDOUT。
DIR 在整个目录树中未找到任何匹配通配符模式以处理 STDERR 的文件时可能输出的错误通过使用 2>nul 将其重定向到设备来抑制NUL。另请阅读有关 Using Command Redirection Operators 的 Microsoft 文章,了解对 2>nul 的解释。当 Windows 命令解释器在执行命令 FOR 在后台启动的单独命令进程中执行嵌入的dir 命令行。
FOR 命令处理从 DIR 的输出中捕获的每一行。 FOR 忽略以 ; 开头的行的默认行为被选项 eol=| 禁用。字符 | 不能用于文件/文件夹名称,因此不能位于文件名或文件路径的开头。 FOR 将水平制表符和空格上的每一行拆分为子字符串的默认行为被选项 delims= 指定一个空的分隔符列表禁用。所以 FOR 确实将每个文件名与完整路径和文件扩展名分配给循环变量I。
注意: eol=| 在这里不是必需的,因为带有选项 /S 的 DIR 会逐行输出带有完整路径的文件名,这使得FOR 处理的行以分号开头。但是文件名可以以分号开头,尽管这对于不使用 DIR 选项 /S 以获取 *.mp3 文件列表而以艺术家和标题为名称的 *.mp3 文件不太可能在没有路径的当前目录中。
重要的是在捕获的文件名列表上运行 FOR,而不是让 FOR 自己递归搜索 MP3 文件,否则它可能会在文件期间发生重命名某些 MP3 文件会因为循环迭代期间的目录条目更改而被跳过。
对于每个文件名,调用子程序RenameFile,将完整的文件名作为第一个用双引号括起来的参数传递给子程序。双引号对于处理文件名或文件路径中包含空格或其中一个字符 &()[]{}^=;!'+,`~ 的文件名也是必需的。
使用子例程而不是直接在 FOR 循环中执行剩余代码,因为这将需要使用延迟的环境变量扩展,如果已处理文件的文件/文件夹名称包含可能出现一个或多个感叹号。
在子程序RenameFile中,当前文件的名称没有路径被分配给环境变量NewName。
接下来对文件名应用字符串替换,以用空格、连字符、空格替换所有连续出现的三个空格。因此,此代码不能 100% 保证连字符实际上是插入艺术家部分和标题部分之间而不是空格,因为没有脚本代码没有访问包含艺术家和标题的大型数据库能够确定什么是艺术家和什么是每个文件名中的标题部分。
然后执行文件重命名,并按照命令REN的要求,指定要重命名的文件用完整路径和文件扩展名不带路径的新名称。
命令 ECHO 可以插入到ren 以首先运行批处理文件,以检查文件重命名是否会按预期完成。
要了解所使用的命令及其工作原理,请打开命令提示符窗口,在其中执行以下命令,并仔细阅读每个命令显示的所有帮助页面。
call /?
dir /?
echo /?
for /?
goto /?
pause /?
ren /?
set /?
另见Where does GOTO :EOF return to?