Windows batch 根据文件名中的时间戳保留最新的N个文件

Windows batch to keep the newest N files based on the timestamp in filename

我需要一个批处理脚本来根据文件名的时间戳仅保留最新的 N 个文件,并且仅当大小大于 150 KB(如果大小更小,则意味着备份文件已损坏并且可以删除)。 我找到了类似的脚本,但仅适用于 Linux.

脚本应首先删除所有大小小于 150 KB 的文件,并使用文件名的时间戳而不是文件的修改日期作为参考保留最新的 N 个文件。

除周末外,此 .txt 文件每天修改几次。 该文件每天备份几次,并在文件名中添加日期和时间。

文件名示例:Test_2019-01-16_21-57-34.txt

路径是:Z:\
OS 是 Windows 8

此任务可以使用以下批处理文件完成:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
pushd "Z:\" || goto :EOF
for /F "eol=| delims=" %%I in ('dir /A-D-H /B /OS "Test_*.txt" 2^>nul') do if %%~zI LEQ 153600 (del "%%I") else goto DeleteOldFiles
:DeleteOldFiles
for /F "skip=5 eol=| delims=" %%I in ('dir /A-D-H /B /O-N "Test_*.txt" 2^>nul') do del "%%I"
popd
endlocal

使用命令 PUSHD 将目录 Z:\ 设置为当前目录,失败时退出批处理文件执行 goto :EOF

下一个命令 FORcmd.exe /c(更准确地说是 %ComSpec% /c)一起在后台命令行的单独命令进程中执行:

dir /A-D-H /B /OS "Test_*.txt" 2>nul

命令DIR输出

  • 非隐藏的 文件的名称 因为选项 /A-D-H (属性不是目录也不是隐藏的)
  • 由于选项 /B
  • ,没有任何附加数据的裸格式
  • 由于选项 /OS
  • ,按大小排序,最小文件在前,最大文件在后
  • 匹配当前目录中的通配符模式Test_*.txt

DIR 输出的关于在当前目录中找不到符合这些条件的任何目录条目的错误消息通过从句柄 STDERR[= 重定向错误消息来抑制149=] 到设备 NUL.

阅读有关 Using Command Redirection Operators 的 Microsoft 文章,了解 2>nul 的解释。重定向运算符 > 必须在 FOR 命令行上使用脱字符 ^ 进行转义,以便在 Windows 命令解释器处理此命令时将其解释为文字字符执行命令 FOR 之前的行,它在后台启动的单独命令进程中执行嵌入式 dir 命令行。

FOR 捕获为处理已启动命令进程的 STDOUT 而编写的所有内容,并在启动后逐行处理捕获的输出 cmd.exe 自行终止。

FOR with option /F 忽略在使用 DIR with option [=17= 时不会出现的空行].

FOR 将使用普通 space 和水平制表符作为分隔符将每一行拆分为子字符串(标记),并仅分配第一个 space/tab 分隔字符串到指定的循环变量 I。通过使用 delims= 定义一个空的字符串定界符列表来禁用此行拆分行为。 delims= 在这种情况下并不是必需的,因为备份文件的文件名不包含 space 字符。

FOR 也会忽略将行拆分为子字符串后的第一个子字符串(不一定是分配给循环变量的子字符串)以分号开头的行,因为 ; 是默认的行尾字符。文件名可以以分号开头,所以最好将行尾字符eol=|eol=?重新定义为竖线或问号,文件名根本不能包含。在这种情况下 eol=| 不是必需的,因为 DIR 的输出只是以 Test_ 开头的文件名,因此默认的 eol=; 不需要被 eol=|.

覆盖

IF 命令比较当前文件的 size 与值 153600 即 150 KiB 并且文件是如果其大小小于或等于该值,则删除。

注: Windows 命令处理器使用带符号的 32 位算法。因此,此 IF 条件无法正确处理超过 2,147,483,647 字节 (2 GiB) 的文件。如果备份文件可以大于 2 GiB,则有必要解决这个带符号的 32 位算术限制。

否则第一个循环退出并跳转到标签 DeleteOldFiles 下面的行,当前文件大于 150 KiB,因为此文件和所有其他文件由 DIR[=149= 输出] 此文件之后的文件大小大于 150 KiB。

第二个 FOR 循环在后台的单独命令进程中再次运行命令 DIR。但是DIR选项/OS/O-N代替,按照文件名倒序输出文件名。 DIR最先输出日期最新的文件名,name中最旧日期的文件名最后输出,因为在文件名中使用国际日期格式。

第二个 FOR 命令行还包含选项 skip=5 以跳过第一个 5 个文件名,即 最新的五个个备份文件。

如果 DIR 输出多于 5 个 个文件名,所有其他文件都比前 5 个 输出文件名被命令 DEL 无条件执行删除 FOR.

最后使用 POPD.

再次将初始当前目录设置为当前目录

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

  • del /?
  • dir /?
  • echo /?
  • for /?
  • goto /?
  • if /?
  • popd /?
  • pushd /?

另请参阅:

  • Single line with multiple commands using Windows batch file 以获得 ||.
  • 的解释

还有一个提示:将 Z:\ 替换为 UNC path if drive letter Z: is assigned to a network resource. And make sure the batch file is executed by an account which has the permissions to access the network resource and delete files in that folder on network resource in case of this batch file is executed as scheduled task. See also