删除所有超过 365 天的文件,但排除某些文件夹

删除所有超过 365 天的文件,但排除某些文件夹

编辑:在听了@Mbu的回答后,我意识到我最初使用文件夹中的前导数字作为排除条件的方法并不正确。我决定使用固定的文件夹列表来排除。


我想通过批处理删除某些文件,但排除要检查的一组给定路径

示例结构

E:.
|───MyBatchFile.cmd
|
├───yes
│   │   no.doc        | file has wrong extension
│   │   yes.cfg
│   │   yes.dat
│   │   yes.hgr
│   │
│   └───yes
│           yes.cfg
│           yes.dat
│           yes.hgr
├───yes
│       yes.cfg
│       no.dat        | file is too new, modified within a year
│       no.hgr        | file is too new, modified within a year
|───no1               | folder is on blacklist
|       importantstuff
└───no2               | folder is on blacklist
        importantstuff

是的文件名表明哪些文件应该删除

我想要的是

从放置批处理的文件夹开始搜索所有文件夹和子文件夹中的所有文件。如果以下所有条件都成立,则删除该文件

  1. 文件扩展名为 .cfg、.dat、.hgr 或 .txt
  2. 修改的时间已超过 365 天
  3. 路径不在黑名单中

我尝试过

基于此问题, 我有:

@echo off
for %%i in (.cfg, .dat, .hdr, .txt) do (
  forfiles /s /m *%%i /d -365 /c "cmd /c del @path"
)
pause

三个问题中有两个已经解决,但是我该如何排除一组给定的文件夹呢?
就像我的例子E:\no1一样。E:\no2

答案1

您可以尝试此脚本,但只有当%%~tA您的区域设置使用 YMD 格式返回文件日期时,它才会起作用。如果不是,则比较将无法按预期进行。

@Echo Off
setlocal enabledelayedexpansion

for /r %%A in (*.cfg;*.dat;*.hdr) do (
  set p=%%~pA
  set numeric=no
  if "!p:~1,1!"=="0" set numeric=yes
  if "!p:~1,1!"=="1" set numeric=yes
  if "!p:~1,1!"=="2" set numeric=yes
  if "!p:~1,1!"=="3" set numeric=yes
  if "!p:~1,1!"=="4" set numeric=yes
  if "!p:~1,1!"=="5" set numeric=yes
  if "!p:~1,1!"=="6" set numeric=yes
  if "!p:~1,1!"=="7" set numeric=yes
  if "!p:~1,1!"=="8" set numeric=yes
  if "!p:~1,1!"=="9" set numeric=yes

  if !numeric!==yes (
    if "%%~tA" LSS "2012-11-08" (
      del %%A
    )
  )
)

endlocal

编辑

我认为我已经设法修改了脚本,使其按您想要的方式工作。我必须摆脱/rswitch 并递归调用子例程,否则黑名单将无法正常工作。黑名单应存储在blacklist.txt脚本所在目录中的文件中。该文件应包含排除文件夹的完整路径(不带引号):

D:\excluded folder1
D:\excluded folder2
D:\included folder\excluded folder3

对于每个未列入黑名单的文件夹,都会调用一个子程序,根据扩展名搜索文件,然后将每个文件的日期与给定的日期进行比较。请彻底测试脚本。我担心它可能会因文件夹名称中包含特殊字符(如%或 )而中断^

@Echo Off
call :browse D:
goto :EOF

:browse
for /d %%A in ("%~1\*") do (
  find /i "%%A" %~dp0blacklist.txt > nul
  if errorlevel 1 (
    call :delete "%%A"
    call :browse "%%A"
  ) else (
    echo SKIP %%A
  )
)
goto :EOF

:delete
for %%A in ("%~1\*.cfg" "%~1\*.dat" "%~1\*.hdr") do (
  if "%%~tA" LSS "2012-10-08" (
    echo DEL  %%A
    del "%%A"
  ) else (
    echo SAVE %%A
  )
)
goto :EOF

答案2

我认为 MBu 的答案比我的好,因为它不依赖于 Robocopy 这样的外部工具。如果黑名单文件夹列表增加,我的 Robocopy 命令就会看起来很丑陋。不过,我想分享我的发现。

你可能会滥用Robocopy删除旧文件、过滤某些扩展名以及从扫描中排除多个目录 - 所有这些都包含在一个命令中。

md C:\TrashMe 
robocopy C:\ C:\TrashMe *.cfg *.hdr *.txt *.dat /MOVE /E /MINAGE:365 /CREATE /R:1 /W:1 /XD C:\dir1 C:\dir2 C:\TrashMe
rd C:\TrashMe

批处理将创建一个名为 的临时垃圾文件夹TrashMe。Robocopy
随后会将所有所需文件(正确的扩展名和修改后的时间戳超过 365 天)移动(而不是复制!)到该垃圾文件夹。您可以使用开关排除多个文件夹/XD
最后一项操作是删除包含所有找到的旧文件的垃圾文件夹。

诀窍是使用/CREATE开关,这样 robocopy 将创建零字节文件而不是实际的源文件。这加快了命令移动和删除部分的速度。


Robocopy 命令详细信息

  • robocopy调用执行程序预安装在 Windows Server 2003、Vista、7 和 8 上
  • C:\是应扫描的源文件夹
  • C:\TrashMe是所有找到的文件的(临时)目标文件夹
  • *.cfg *.hdr *.txt *.dat是通配符,将过滤某些文件扩展名
  • /MOVE将剪切并粘贴所有找到的文件,而不是复制并粘贴它们
  • /E将扫描所有子目录
  • /MINAGE:365将排除所有超过 365 天的文件
  • /CREATE将创建从零开始的文件,而不是原始源文件
  • /R:1 /W:1如果文件被锁定且无法删除,则重试次数和等待时间是多少
  • /XD C:\dir1 C:\dir2 C:\TrashMe是我的黑名单文件夹列表。我还必须包含 TrashMe 文件夹,因为它位于源文件夹中

相关内容