windows - 如何批量删除文超过n天的文件?

  显示原文与译文双语对照的内容

我正在寻找一种方式来删除所有文件比 7天MS-DOS批处理文件。 我在网络上搜索,发现一些例子有数百行代码,以及其他需要安装额外的命令行 实用工具来完成这项任务。

类似的事情可以在bash 做几行代码。 Windows 中的批处理文件至少可以远程完成一些事情。 我在寻找一个解决方案,在一个标准的工作 Windows 命令提示符下,没有任何额外的工具。 请不要使用PowerShell或者 Cygwin 。

时间:

享受:


forfiles -p"C:whatever" -s -m *.* -d <number of days> -c"cmd/c del @path"

有关详细信息,请参阅 forFile文档

有关更多信息,请参阅的A-Z索引 Windows XP 命令行

如果你没有 forfiles 安装在你的机器上,复制从任何 Windows 2003服务器在 %WinDir%system32 Windows xp机器这是可能的因为exeWin2003和winxp之间完全兼容。

Windows 和 Windows Server的更新版本默认安装了它。

更新 Win7: 语法已经改变了一点,因此更新的命令是:


forfiles -p"C:whatever" -s -m *.*/D -<number of days>/C"cmd/c del @path"

运行以下命令:


ROBOCOPY C:source C:destination/move/minage:7
del C:destination/q

将所有文件通过robocopy移动到另一个位置,然后在该路径上执行删除命令,你就好了。

如果你有一个包含大量数据的目录,你可以使用 /mir switch

好无聊,想出了这个,它包含我的linux版本的一个贫穷的男人时代替代有限的日常使用( 没有时间保留):

7daysclean.cmd


@echo off
setlocal ENABLEDELAYEDEXPANSION
set day=86400
set/a year=day*365
set/a strip=day*7
set dSource=C:temp

call :epoch %date%
set/a slice=epoch-strip

for/f"delims=" %%f in ('dir/a-d-h-s/b/s %dSource%') do (
 call :epoch %%~tf
 if!epoch! LEQ %slice% (echo DELETE %%f ^(%%~tf^)) ELSE echo keep %%f ^(%%~tf^)
)
exit/b 0

rem Args[1]: Year-Month-Day
:epoch
 setlocal ENABLEDELAYEDEXPANSION
 for/f"tokens=1,2,3 delims=-" %%d in ('echo %1') do set Years=%%d& set Months=%%e& set Days=%%f
 if"!Months:~0,1!"=="0" set Months=!Months:~1,1!
 if"!Days:~0,1!"=="0" set Days=!Days:~1,1!
 set/a Days=Days*day
 set/a _months=0
 set i=1&& for %%m in (31 28 31 30 31 30 31 31 30 31 30 31) do if!i! LSS!Months! (set/a _months=!_months! + %%m*day&& set/a i+=1)
 set/a Months=!_months!
 set/a Years=(Years-1970)*year
 set/a Epoch=Years+Months+Days
 endlocal& set Epoch=%Epoch%
 exit/b 0

_ _Usage_ _

设置/a strip=day*7 : 更改要保留的天数的7

dsource=c: temp: 这是检查文件的起始目录。

_ _Notes_ _

这是non-destructive代码,它会显示发生了什么。 更改:

epoch LEQ %slice% ( 回显删除 %%f ^ ( %%~tf^ ) ) 或者 echo 保持 %%f ^ ( %%~tf^ )

类似于:

epoch LEQ %slice% del/f %%f

所以文件实际上会被删除

2月 : hard-coded 28天。 Bisextile年是一个地狱,真的。 如果有人有一个不会添加 10行代码的想法,那么继续,然后把它添加到我的代码中。

时代:我没有考虑的时间,因为需要删除文件超过一个特定日期,小时/分钟会删除文件从意味着保持一天。

我提到我讨厌这个编辑器的auto-formating? 它删除了空行,copy-paste是地狱。

我希望这可以帮到你。

查看我的答案类似的问题:


REM del_old.bat
REM usage: del_old MM-DD-YYY
for/f"tokens=*" %%a IN ('xcopy *.*/d:%1/L/I null') do if exist %%~nxa echo %%~nxa>> FILES_TO_KEEP.TXT
for/f"tokens=*" %%a IN ('xcopy *.*/L/I/EXCLUDE:FILES_TO_KEEP.TXT null') do if exist"%%~nxa" del"%%~nxa"

删除超过给定日期的文件。 我确信可以修改为从当前日期返回七天。

更新: 我注意到HerbCSO在上面的脚本上已经改进了。 我建议使用的版本


forfiles/p"v:"/s/m *.*/d -3/c"cmd/c del @path"

你应该做 /d -3 ( 3天之前) 这对我很有用。 所有复杂的批次都可以在垃圾箱里。 同时 forfiles 不支持UNC路径,因此请与特定驱动器建立网络连接。

我的命令是


forfiles -p"d:logs" -s -m*.log -d-15 -c"cmd/c del @PATH@FILE" 

@PATH - 只是我的例子中的路径,所以我不得不使用 @PATH@FILE

forfiles/? 也不能为我工作,但是 forfiles ( 没有"") 工作良好。

我唯一的问题是: 如何添加多个遮罩( 例如" 。log| 。bak")?

所有这些关于 forfiles.exe 我下载这里(赢得xp)

但是如果你使用 Windows Server forfiles.exe 应该已经存在并且它与ftp版本不同。 这就是为什么我应该修改命令。

对于 Windows Server 2003,我使用以下命令:


forfiles -p"d:Backup" -s -m *.log -d -15 -c"cmd/c del @PATH"

复制这里代码并将它的保存为 DelOldFiles.vbs.

仅在命令提示符中使用: cscript DelOldFiles.vbs 15

15表示删除过去 15天以前的文件。


 'copy from here
 Function DeleteOlderFiles(whichfolder)
 Dim fso, f, f1, fc, n, ThresholdDate
 Set fso = CreateObject("Scripting.FileSystemObject")
 Set f = fso.GetFolder(whichfolder)
 Set fc = f.Files
 Set objArgs = WScript.Arguments
 n = 0
 If objArgs.Count=0 Then
 howmuchdaysinpast = 0
 Else
 howmuchdaysinpast = -objArgs(0)
 End If
 ThresholdDate = DateAdd("d", howmuchdaysinpast, Date) 
 For Each f1 in fc
 If f1.DateLastModified<ThresholdDate Then
 Wscript.StdOut.WriteLine f1
 f1.Delete
 n = n + 1 
 End If
 Next
 Wscript.StdOut.WriteLine"Deleted" & n &" file(s)."
 End Function

 If Not WScript.FullName = WScript.Path &"cscript.exe" Then
 WScript.Echo"USAGE ONLY IN COMMAND PROMPT: cscript DelOldFiles.vbs 15" & vbCrLf &"15 means to delete files older than 15 days in past."
 WScript.Quit 0 
 End If

 DeleteOlderFiles(".")
 'to here

关于 7daysclean.cmd的修改如何考虑闰年?

可以在少于 10行的编码中完成 !


set/a Leap=0
if (Month GEQ 2 and ((Years%4 EQL 0 and Years%100 NEQ 0) or Years%400 EQL 0)) set/a Leap=day
set/a Months=!_months!+Leap


由Mofi编辑:

上述条件由 J.R 提供。 由于语法无效,计算总是为

Month GEQ 2 也是错误的,因为添加 86400秒再多一天必须做在一个闰年仅为3个月至12月,但不是2月。

工作代码来考虑闰日-在今年只有在批处理文件 7daysclean.cmdJay发布的是:


set"LeapDaySecs=0"
if %Month% LEQ 2 goto CalcMonths
set/a"LeapRule=Years%%4"
if %LeapRule% NEQ 0 goto CalcMonths
rem The other 2 rules can be ignored up to year 2100.
set/A"LeapDaySecs=day"
:CalcMonths
set/a Months=!_months!+LeapDaySecs

...