【问题标题】:Renaming the last created file with CMD / batch file (append suffix to original file name)用 CMD / 批处理文件重命名最后创建的文件(将后缀添加到原始文件名)
【发布时间】:2020-10-11 21:37:35
【问题描述】:

我正在尝试使用批处理文件在一个充满文件的目录中重命名最后创建的文件(仅该文件)。

目录有这样的文件:

2020-06-21 23-56-26.mp4
2020-06-21 23-54-30.mp4
2020-06-21 23-48-40.mp4
2020-06-21 23-34-06.mp4

我想获取最后创建的文件并将后缀附加到现有文件名。

所以例如2020-06-21 23-56-26.mp4变成2020-06-21 23-56-26_test.mp4

我在网上找到了很多例子,但是我遇到了一些问题。

测试 1:

for /f "delims=" %%i in ('dir /b /a-d /od /t:c "C:\vids\*.mp4"') do set LAST=%%i
echo ren "C:\vids\%LAST%" "%%~nLAST_test%%~xLAST"

这几乎可以满足我的要求,但是重命名部分 "%%~nLAST_test%%~xLAST" 不起作用。似乎变量替换被忽略了。

我得到输出:ren "C:\vids\2020-06-21 23-57.mp4" "%~NLAST_test%~XLAST",这意味着文件被重命名为 %~nLAST_test%~xLAST

测试 2:

for /f "delims=" %%a in ('dir /b /a-d /od /t:c "C:\vids\*.mp4"') do echo ren "%%~a" "%%~Na_test%%~Xa"

此重命名命令中使用的变量替换有效,但它会重命名文件夹中的每个文件,而不是仅重命名最近创建的文件。

我是否遗漏了一些括号或其他语法?

【问题讨论】:

  • Test 1 上:~-modifiers 仅限于 for 元变量和参数引用,但它们不能用于普通环境变量...

标签: windows batch-file cmd rename


【解决方案1】:
for /f "delims=" %%a in ('dir /b /a-d /od /t:c "C:\vids\*.mp4"') do echo ren "%%~a" "%%~Na_test%%~Xa"

此重命名命令中使用的变量替换有效,但它会重命名文件夹中的每个文件,而不是仅重命名最近创建的文件

假设上述工作如所述(这并不明显,因为似乎缺少更多上下文),请尝试以下操作来反转 dir 顺序和 ren first 项,仅.

set "DONE="
for /f "delims=" %%a in ('dir /b /a-d /o-d /t:c "C:\vids\*.mp4"') do if not defined DONE set "DONE=1" & echo ren "%%~a" "%%~Na_test%%~Xa"

[ EDIT ] 正如评论中所指出的,上面引用的 OP 代码仅在执行 for 循环时当前目录为 C:\vids 时才有效,否则 ren 将在错误的目录中寻找%%~a 文件。

可以通过将ren 行上的"C:\vids\%%~a" 替换为"C:\vids\%%~a" 或暂时将C:\vids 设置为当前目录来删除不必要的假设,如下所示。

pushd "C:\vids"
set "DONE="
for /f "delims=" %%a in ('dir /b /a-d /o-d /t:c "*.mp4"') do if not defined DONE set "DONE=1" & echo ren "%%~a" "%%~Na_test%%~Xa"
popd

【讨论】:

    【解决方案2】:

    简单的解决办法是:

    @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 输出的第一个文件名完全分配给循环变量IFOR 运行命令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 /?

    【讨论】:

    • 这似乎可行,但我不明白您为什么使用/O-N 代替dir 排序选项而不是/O-D。据我了解,N 用于名称,而D 用于日期和时间。此外,"%%~nI_test.%%~xI" 有一点错误,那里不需要.。感谢您的帮助!
    • @crackerbear 我已经在我的回答中解释了为什么在这种情况下所有文件名都包含国际格式的日期/时间,使用选项/O-N(按名称反向排序)而不是/O-D(按日期反向排序)与/TW(最后修改时间)或/TC(此目录中文件的创建日期)。如果您想忽略文件名中的日期/时间并使用目录C:\vids 中文件的最后修改日期或创建日期,当然可以使用/O-D /TW/O-D /TC 而不是/O-N
    猜你喜欢
    • 2013-07-11
    • 1970-01-01
    • 2017-09-16
    • 2019-12-04
    • 1970-01-01
    • 2020-10-16
    • 2019-06-08
    • 2023-03-25
    • 1970-01-01
    相关资源
    最近更新 更多