如何根据文件路径中的目录以递归方式删除早于特定日期的* .bak文件?

时间:2017-07-27 14:57:41

标签: windows batch-file

我正在为Windows 7编写批处理文件。

我目前有一个代码可以从我们的站点管理文件夹中的主站文件夹中删除旧备份。这是代码:

for /d %%A in ("Y:\*.*") do del /s /q /f "%%A\masters\*.bak"

但是我需要将其编码为仅删除超过3年的内容,这将是以下代码:

forfiles /P "Y:\" /S /D -1096 /M *.bak /C "cmd /C del @path"

但是我需要顶部代码中的内容,以便我可以从173个站点管理文件夹中的masters文件夹中删除所有* .bak文件。我正在扯掉我的头发搞清楚这一点。我无法从其他文件夹中删除* .bak文件。

我已尝试合并代码,但批处理文件中的命令行下方无法正常工作:

forfiles /S /D -1096 /M *.bak /C "cmd /C for /d %%A in ("Y:\*.*") do del /s /q /f "%%A\masters\*.bak"

如果文件路径中的第二个目录为masters并且所有其他* .bak文件保持较新或者在文件中第二个目录的目录中,如何删除目录树中任何位置超过3年的所有* .bak文件路径不是masters

1 个答案:

答案 0 :(得分:0)

首先使用以下命令创建批处理文件C:\Temp\DeleteBackup.bat

@echo off
set "BackupFileName=%~1"
if not "%BackupFileName:\masters\=%" == "%BackupFileName%" ECHO del "%BackupFileName%"

此批处理代码通过从字符串比较的左参数中删除此字符串不区分大小写来检查具有完整路径和文件扩展名的文件名是否包含\masters\

如果由于路径中包含\masters\而剩余的字符串与未修改的文件名字符串不相等,则 IF 条件为true,如果不存在,则删除备份文件命令 ECHO ,导致只显示 DEL 命令行。

例如,备份文件的完整列表是:

Y:\masters\Level2\Level3\Level4\Level5\Test1.bak
Y:\Folder2\masters\Level3\Test2.bak
Y:\Folder3\Level2\masters\Level4\Test3.bak
Y:\Folder4\Level2\Level3\Level4\Level5\Test4.bak
Y:\Folder5\Level2\Test5.bak
Y:\Folder6\Level2\Level3\Level4\Level5\Level6\Test6.bak
Y:\Folder7\masters\Test7.bak

删除的文件为:

Y:\masters\Level2\Level3\Level4\Level5\Test1.bak
Y:\Folder2\masters\Level3\Test2.bak
Y:\Folder3\Level2\masters\Level4\Test3.bak
Y:\Folder7\masters\Test7.bak

剩下的文件是:

Y:\Folder4\Level2\Level3\Level4\Level5\Test4.bak
Y:\Folder5\Level2\Test5.bak
Y:\Folder6\Level2\Level3\Level4\Level5\Level6\Test6.bak

然后在批处理文件中使用:

forfiles /P "Y:\" /S /D -1096 /M *.bak /C "C:\Temp\DeleteBackup.bat @PATH"

当然可以修改DeleteBackup.bat以检查第二个目录层次结构级别中的目录是否为masters

@echo off
for /F "tokens=3 delims=\" %%I in ("%~1") do if /I "%%I" == "masters" ECHO del "%~1"

此代码将从文件上方的完整列表中删除:

Y:\Folder2\masters\Level3\Test2.bak
Y:\Folder7\masters\Test7.bak

剩下的文件是:

Y:\masters\Level2\Level3\Level4\Level5\Test1.bak
Y:\Folder3\Level2\masters\Level4\Test3.bak
Y:\Folder4\Level2\Level3\Level4\Level5\Test4.bak
Y:\Folder5\Level2\Test5.bak
Y:\Folder6\Level2\Level3\Level4\Level5\Level6\Test6.bak

Robert Chizmadia Jr.在已删除的评论中提问:

是否可以使用GOTO而不是在FORFILES命令行上调用另一个批处理文件?

关于这个附加问题的答案:

FORFILES 不是cmd.exe的内部命令,例如 FOR 。它是一个存储在目录%SystemRoot%\System32中的控制台应用程序,如果使用的Windows版本已预先安装它。

FORFILES 选项/C之后指定的执行命令必须是可执行文件或脚本。这就是为什么当{strong> DEL 的Windows命令解释器cmd /C的内部命令应由 FORFILES 执行时,始终使用cmd.exe的原因完整命令为%SystemRoot%\System32\cmd.exe /C

因此,无法在 FORFILES 命令中使用 GOTO 这样的命令,因为没有名称为 GOTO 的可执行文件或脚本。< / p>

FOR 循环中的 GOTO 退出循环,因此在批处理文件中的另一个位置继续解释批处理文件的命令行。

但是,可以使用相同的批处理文件进行文件路径评估和备份文件删除,以用于运行 FORFILES 命令。

示例1,批处理文件不需要任何默认操作参数:

@echo off
if not "%~1" == "" (
    for /F "tokens=3 delims=\" %%I in ("%~1") do if /I "%%I" == "masters" ECHO del "%~1"
    goto :EOF
)

%SystemRoot%\System32\forfiles.exe /P "Y:\" /S /D -1096 /M *.bak /C "%~f0 @PATH"

如果使用参数执行此批处理文件,它将运行 FOR 循环,以检查文件路径中的第二个目录是否为masters并在删除此文件后删除此文件<强> ECHO 即可。否则,在没有任何参数的情况下启动批处理文件时,批处理文件将运行 FORFILES 可执行文件。

示例2,批处理文件需要一个或多个默认操作参数:

@echo off
if "%~1" == "#Delete:Backup#" (
    for /F "tokens=3 delims=\" %%I in ("%~2") do if /I "%%I" == "masters" ECHO del "%~2"
    goto :EOF
)

rem Other commands processing the parameters.

%SystemRoot%\System32\forfiles.exe /P "Y:\" /S /D -1096 /M *.bak /C "%~f0 #Delete:Backup# @PATH"

rem More commands executed after the deletion of the backup files.

这与示例1几乎相同,不同之处在于,如果运行批处理文件时使用的第一个参数区分大小写为字符串#Delete:Backup#,则批处理文件需要将备份文件的名称作为第二个参数。如果文件路径中的第二个目录为masters,则删除完整路径。

与所有批处理代码示例一样,在此代码示例中,del命令之前必须删除命令 ECHO 才能真正执行删除备份文件。

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

  • echo /?
  • for /?
  • forfiles /?
  • goto /?
  • if /?
  • set /?