简单的解决办法是:
@for /F "eol=| delims=" %%I in ('dir "C:\vids\????-??-?? ??-??-??.mp4" /A-D /B /O-N 2^>nul') do @ren "C:\vids\%%I" "%%~nI_test.%%~xI" & goto :EOF
国际日期格式的文件名中带有日期/时间的文件名可以让 DIR 输出与通配符模式匹配的文件名,按名称反向排序,从而首先获得输出@987654324 @。
FOR 在后台运行另一个命令进程,其中%ComSpec% /c 和' 之间的命令行作为附加参数附加。所以执行是在Windows安装到C:\Windows:
C:\Windows\System32\cmd.exe /c dir "C:\vids\????-??-?? ??-??-??.mp4" /A-D /B /O-N 2>nul
DIR 在指定目录C:\vids 中搜索
- 只是文件,因为选项
/A-D(属性不是目录)
- 匹配通配符模式
????-??-?? ??-??-??.mp4和
- 由于选项
/B 仅输出不带路径的文件名,以裸格式输出到 STDOUT
- 由于选项
/O-N,因此按名称反向排序,这意味着在这种情况下,文件名中具有最新日期/时间的 MP4 文件在前。
可能是 DIR 没有找到任何符合这些条件的文件,在这种情况下 DIR 会向 STDERR 输出错误消息,即通过将其重定向到设备 NUL 来抑制。
阅读有关Using command redirection operators 的Microsoft 文章,了解2>nul 的解释。重定向运算符 > 必须在 FOR 命令行上使用插入字符 ^ 转义,以便在 Windows 命令解释器在执行命令 FOR之前处理此命令行时解释为文字字符> 在后台启动的单独命令进程中执行嵌入的dir 命令行。
FOR 捕获为处理后台命令进程的 STDOUT 而编写的所有内容,并在启动后逐行处理此输出 cmd.exe 在完成 执行后自行终止目录。
FOR 带有选项 /F 会忽略此处未出现的空行。默认情况下,所有其他行将使用普通空格和水平制表符作为字符串分隔符拆分为子字符串。这里不需要这种拆分行为,因为文件名肯定包含空格字符。出于这个原因,选项delims= 用于定义一个空的字符串分隔符列表,它完全禁用行拆分行为,因此整个文件名被分配给指定的循环变量I。
FOR 带有选项/F 也将忽略分割线后第一个子字符串以分号开头的行,分号是默认的行尾字符。选项eol=| 将行尾字符重新定义为竖线,文件名永远不能包含该竖线。 eol=| 在这里并不真正需要,因为没有文件名以分号开头。
DIR 输出的第一个文件名完全分配给循环变量I,FOR 运行命令REN 重命名文件在文件扩展名后面附加_test。
FOR 将处理下一个在这种情况下不需要的文件名。因此,goto :EOF 被添加为第二个命令,在命令ren 之后无条件执行以退出批处理文件处理。
也可以使用goto FileRenamed 之类的东西,并将:FileRename 行作为下一行之一,以退出循环并继续处理批处理文件,并使用:FileRename 行下方的行,例如:
@echo off
for /F "eol=| delims=" %%I in ('dir "C:\vids\????-??-?? ??-??-??.mp4" /A-D /B /O-N 2^>nul') do ren "C:\vids\%%I" "%%~nI_test.%%~xI" & goto FileRenamed
echo ERROR: Found no MP4 file in folder C:\vids to rename!
echo/
pause
goto :EOF
:FileRenamed
echo Newest file renamed, continue batch file processing ...
要了解所使用的命令及其工作原理,请打开command prompt 窗口,在其中执行以下命令,并仔细阅读每个命令显示的所有帮助页面。
dir /?
echo /?
for /?
goto /?
pause /?
ren /?