如何将文件名中包含“-yyyy mm dd hh mm”的所有文件重命名为日期/时间之前的部分?

问题描述 投票:0回答:2

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

 - 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

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

我只是想使用像

 - ???? ?? ?? ?? ??
这样的通配符。

windows batch-file
2个回答
1
投票

您对

- ???? ?? ?? ?? ??
通配符的猜测很好,但这会匹配任何字符,因此它也会匹配
- 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
,您需要从
echo
 之后删除 
do


1
投票

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

@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]"

阅读有关 使用命令重定向运算符的 Microsoft 文档,了解

2>nul
|
的说明。重定向运算符
>
|
必须在
FOR
命令行上使用脱字符号 ^ 进行转义,以便在 Windows 命令解释器在执行执行嵌入命令的命令 FOR 之前处理此命令行时将其解释为文字字符线。

命令DIR搜索

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

命令 DIR 可能无法找到与这些条件匹配的任何文件系统条目,从而导致输出错误消息来处理 STDERR(标准错误),通过使用

2>nul
将其重定向到设备NUL

文件名使用

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

FINDSTR处理后台命令进程的STDOUT(标准输出)的输出是通过处理批处理文件的

cmd.exe
捕获的,并且在执行命令行后cmd.exe自行关闭后,
FOR
处理捕获的行完成了。

文件名必须完全分配给循环变量

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

在启用本例所需的延迟变量扩展之前,将不带文件扩展名的文件名和文件扩展名分配给两个环境变量。

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

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

阅读此答案,了解有关命令 SETLOCALENDLOCAL 的详细信息,因为除了启用/禁用延迟扩展之外,还有更多内容。

要了解所使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并完整、仔细地阅读每个命令显示的帮助页面。

  • dir /?
  • echo /?
  • endlocal /?
  • findstr /?
  • for /?
  • ren /?
  • setlocal /?
© www.soinside.com 2019 - 2024. All rights reserved.