如何将所有文件名中带有“-yyyy mm dd hh mm”的文件重命名为date/time之前的部分?

How to rename all files with " - yyyy mm dd hh mm" in file name to just the part before date/time?

我想重命名当前目录中的所有文件,并从文件名中删除 - yyyy mm dd hh mm

例如(之前->之后):

文件名 - 2022 03 31 13 28->文件名
a - 2022 03 31 13 28->a
b - 2022 02 28 13 28->b
c - 2022 01 03 13 28->c

我不知道如何使用批处理脚本来做到这一点。

我只是想使用像 - ???? ?? ?? ?? ?? 这样的通配符。

你对 - ???? ?? ?? ?? ?? 通配符的猜测很好,但是它会匹配任何字符,所以它也会匹配 - This is my ID 01

所以使用findstr的正则表达式会更健壮一些(为了演示的目的,我使用.txt作为dir的扩展):

@echo off
for /F "tokens=1*delims=- " %%i in ('dir /b /a-d *.txt ^| findstr /R /C:"[a-z][ ][-][ ][0-9]*[ ][0-9]*[ ][0-9]*[ ][0-9]*"') do echo ren "%%i - %%j" "%%i%%~xj"

注1 以上是针对batch-file的。如果您需要从 cmd 提示中 运行,请从每组 %%

中删除一个 %

注2这个命令只会echo结果。要使其实际执行 rename,您需要从 do

之后删除 echo

此文件重命名任务可以使用以下批处理文件:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "eol=| delims=" %%I in ('dir "* - ???? ?? ?? ?? ??.*" /A-D /B 2^>nul ^| %SystemRoot%\System32\findstr.exe /R /C:". - [12][09][01234567879][0123456789] [01][0123456789] [0123][0123456789] [012][0123456789] [012345][0123456789]"') do (
    set "FileName=%%~nI"
    set "FileExt=%%~xI"
    setlocal EnableDelayedExpansion
    ren "!FileName!!FileExt!" "!FileName:~0,-19!!FileExt!"
    endlocal
)
endlocal

在后台执行 Windows 安装到 C:\Windows:

C:\Windows\System32\cmd.exe /c dir "* - ???? ?? ?? ?? ??.*" /A-D /B 2>nul | C:\Windows\System32\findstr.exe /R /C:". - [12][09][01234567879][0123456789] [01][0123456789] [0123][0123456789] [012][0123456789] [012345][0123456789]"

阅读有关 Using command redirection operators 的 Microsoft 文档,了解 2>nul| 的解释。重定向运算符 >| 必须在 FOR 命令行上使用脱字符 ^ 进行转义,以便在 [=126= 时将其解释为文字字符] 命令解释器在执行执行嵌入式命令行的命令 FOR 之前处理此命令行。

命令DIR搜索

  • 在当前目录
  • 由于选项 /A-D(属性而非目录)仅适用于文件
  • 匹配通配符模式 * - ???? ?? ?? ?? ??.*,它也适用于没有文件扩展名的文件
  • 并且由于选项 /B(裸格式)而只输出匹配的文件名。

命令 DIR 可能无法找到符合这些条件的任何文件系统条目,这会导致输出错误消息以处理 STDERR(标准错误)通过使用 2>nul 将其重定向到设备 NUL.

来抑制

文件名使用 | 重定向到 FINDSTR 搜索行(文件名)与过滤掉所有文件名的正则表达式匹配的字符串由 DIR 使用指定的通配符模式找到,但在格式为 - yyyy MM dd HH mm 的文件扩展名之前并没有真正在末尾分别具有 date/time,这意味着年份中有世纪范围为 1000 到 2999,月份为 00 到 19 的两位数,月份的日期为 00 到 39 的两位数,小时为 00 到 29 的两位数,分钟为 00 到 29 的两位数59. 正则表达式对于 date/time 验证来说并不完美,但对于这个任务应该足够好了。

FINDSTR处理后台命令进程STDOUT(标准输出)的输出被cmd.exe处理捕获批处理文件和 FOR 在命令行执行完成后 cmd.exe 自行关闭后处理捕获的行。

文件名必须完全分配给循环变量 I 而不是使用普通 space 和水平制表符作为字符串分隔符将它们分开,并且只分配第一个 space/tab分隔字符串循环变量 I 不以 ; 开头。因此,FOR /F 选项 eol=| 将行尾字符从分号重新定义为竖线,任何文件名都不能包含该竖线,以避免忽略文件名开头使用分号和选项 delims= 定义一个空的字符串定界符列表以关闭将行拆分为标记(子字符串)。

没有文件扩展名的文件名和文件扩展名被分配给两个环境变量,然后才启用这种情况下所需的延迟变量扩展。

接下来将文件重命名,删除不带扩展名的文件名的最后 19 个字符,同时保留文件扩展名。此解决方案也适用于包含 space 或 date/time 部分要删除的连字符的文件名。

然后恢复禁用延迟变量扩展的先前执行环境以处理正确的包含一个或多个感叹号的文件名。

阅读 以获取有关命令 SETLOCALENDLOCAL 的详细信息,因为在背景中不仅有 enabling/disabling延迟扩张。

为了了解使用的命令及其工作原理,请打开 command prompt window,在那里执行以下命令,并仔细阅读每个命令显示的所有帮助页面。

  • dir /?
  • echo /?
  • endlocal /?
  • findstr /?
  • for /?
  • ren /?
  • setlocal /?