用批处理文件(.bat 或 .cmd)实现复杂重命名,核心在于利用 for 循环 结合 变量延迟展开(Delayed Expansion) 以及 字符串截取/替换 功能。
CMD 的原生字符串处理能力虽然不如 PowerShell 灵活,但通过一些技巧,完全可以应对大多数复杂的重命名需求(如:提取特定字符、添加序号、日期格式化、条件判断等)。
在编写复杂逻辑前,你的批处理文件头部必须包含以下两行,否则变量在循环中无法实时更新:
@echo off
setlocal enabledelayedexpansion
@echo off:隐藏命令本身,只显示结果,让界面更干净。
setlocal enabledelayedexpansion:最关键的一步。它允许你在循环内部使用 !变量名! 的语法来实时获取变量的最新值(如果用 %变量名%,获取的永远是循环开始前的旧值)。
需求:将 photo.jpg, image.png 等文件重命名为 01_photo.jpg, 02_image.png,且序号自动补零(1-9 前面加 0)。
代码示例 (add_number.bat):
@echo off
setlocal enabledelayedexpansion
set count=0
:: 遍历当前目录下所有 jpg 和 png 文件
for %%f in (*.jpg *.png) do (
set /a count+=1
:: 判断是否需要补零 (如果小于10)
if !count! LSS 10 (
set "newname=0!count!_%%f"
) else (
set "newname=!count!_%%f"
)
:: 执行重命名
echo 重命名: "%%f" -> "!newname!"
ren "%%f" "!newname!"
)
pause
技巧解析:
%%f:在批处理文件中,for 循环变量必须用两个百分号 %%。
!count!:使用感叹号获取实时更新的计数值。
LSS:Less Than 的缩写,用于数值比较。
需求:文件名为 20260302_report_final.docx,只想保留中间的 report 部分,重命名为 report.docx。或者更复杂点,只保留第 5 到第 10 个字符。
CMD 提供了强大的字符串截取语法:%variable:~start,length%
代码示例 (extract_part.bat):
@echo off
setlocal enabledelayedexpansion
for %%f in (*.docx) do (
set "fullname=%%f"
:: 获取不带扩展名的文件名
set "nameonly=%%~nf"
:: 假设格式固定:前8位是日期,我们要从第9位开始截取
:: 语法:!var:~起始位置,长度!
:: 注意:起始位置从 0 开始计数。第9个字符的索引是 8。
set "newname=!nameonly:~8,10!"
:: 如果截取后为空,防止出错,可以加个判断,这里简化处理
if not "!newname!"=="" (
echo 重命名: "%%f" -> "!newname!.docx"
ren "%%f" "!newname!.docx"
)
)
pause
技巧解析:
%%~nf:提取文件名(不含路径和扩展名)。
!nameonly:~8,10!:从索引 8 开始(即第 9 个字符),截取 10 个字符。如果不写长度,则截取到末尾。
需求:将所有文件名中的 2025 替换为 2026,或者将空格替换为下划线 _。
虽然 ren 支持通配符替换,但在批处理中用字符串替换更可控,尤其是涉及多个替换规则时。
代码示例 (replace_text.bat):
@echo off
setlocal enabledelayedexpansion
for %%f in (*) do (
if not "%%f"=="%~nx0" goto :process :: 跳过脚本文件自己
set "oldname=%%f"
set "newname=!oldname:2025=2026!" :: 将 2025 替换为 2026
set "newname=!newname: =_!" :: 将空格替换为下划线
:: 只有当名字确实发生变化时才重命名
if not "!oldname!"=="!newname!" (
echo 重命名: "!oldname!" -> "!newname!"
ren "!oldname!" "!newname!"
)
)
pause
技巧解析:
!var:old=new!:这是 CMD 的原生字符串替换语法,非常高效。
if not "%%f"=="%~nx0":这是一个防呆设计,防止脚本把自己重命名了导致运行中断。%~nx0 代表当前脚本的文件名。
需求:只重命名大小超过 1MB 的文件,并在前面加上 BIG_ 前缀。
代码示例 (condition_rename.bat):
@echo off
setlocal enabledelayedexpansion
for %%f in (*) do (
if exist "%%f" (
:: 获取文件大小 (单位字节)
set "size=%%~zf"
:: 1MB = 1048576 字节
if !size! GTR 1048576 (
set "newname=BIG_%%f"
echo [大文件] 重命名: "%%f" -> "!newname!"
ren "%%f" "!newname!"
)
)
)
pause
技巧解析:
%%~zf:获取文件的大小(字节数)。
GTR:Greater Than 的缩写,用于数值比较。
需求:不仅处理当前文件夹,还要处理所有子文件夹里的文件。只需在 for 命令中加入 /r 参数。
代码示例 (recursive_rename.bat):
@echo off
setlocal enabledelayedexpansion
:: /r 表示递归当前目录及所有子目录
for /r %%f in (*.tmp) do (
echo 发现临时文件: "%%f"
:: 注意:ren 命令不能跨路径,所以只能改文件名,不能改路径
:: %%~nf 是文件名,%%~xf 是扩展名
ren "%%f" "OLD_%%~nf%%~xf"
)
pause
注意:ren 命令本身不支持移动文件(改变路径),它只能在原目录下改名。如果需要移动文件,需要配合 move 命令。
批处理文件的复杂重命名能力可以总结为公式:
For 循环遍历 + Set 变量处理 (截取/替换/计算) + If 条件判断 + Ren 执行
虽然写法比 PowerShell 略显繁琐,但它无需额外环境,双击即可运行,是系统维护和批量处理的轻量级神器。对于超复杂的逻辑(如正则表达式匹配),建议还是调用 PowerShell,但在 90% 的日常场景中,上述批处理技巧已经足够强大。