批处理文件以删除超过N天的文件

时间:2020-03-05 18:49:46  来源:igfitidea点击:

我正在寻找一种删除批处理文件中所有7天以上的文件的方法。我在网上搜索,发现了一些包含数百行代码的示例,还有一些示例需要安装额外的命令行实用程序才能完成任务。

只需几行代码即可在BASH中完成类似的操作。似乎可以对Windows中的批处理文件执行至少在远程上容易的事情。我正在寻找一种可以在标准Windows命令提示符下运行且没有任何其他实用程序的解决方案。请不要使用PowerShell或者Cygwin。

解决方案

回答

享受:

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

有关更多详细信息,请参见forfile文档。

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

如果计算机上没有安装" forfiles",请将其从任何Windows Server 2003复制到WindowsXP计算机上,位于"%WinDir%\ system32 "。因为EXE在Windows Server 2003和WindowsXP之间完全兼容,所以这是可能的。

Windows和Windows Server的更高版本默认情况下已安装它。

对于Windows7:

语法略有变化。因此,更新后的命令为:

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

回答

除了复杂的bat文件或者Windows脚本之外,我们可能不会找到完全不安装的解决方案。我使用delen,将其放在系统目录中,然后像在任何bat文件中的常规del命令一样使用它。

回答

我们也许可以做到这一点。我们可以看一下这个问题,举一个简单的例子。当我们开始比较日期时,就会变得很复杂。判断日期是否更大可能很容易,但是有很多情况需要考虑是否需要实际获得两个日期之间的差额。

换句话说,除非我们真的不能使用第三方工具,否则请不要尝试发明它。

回答

Ok有点无聊,并提出了这个建议,其中包含我的一个穷人的Linux时代替换版本,该版本仅限于日常使用(无时间限制):

7天清理

@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

用法

set / a strip = day * 7:将要保留的天数更改为7.

set dSource = C:\ temp`:这是检查文件的起始目录。

笔记

这是非破坏性的代码,它将显示会发生的情况。

改变 :

if !epoch! LEQ %slice% (echo DELETE %%f ^(%%~tf^)) ELSE echo keep %%f ^(%%~tf^)

到这样的东西:

if !epoch! LEQ %slice% del /f %%f

因此实际上删除了文件

2月:硬编码为28天。难忘的岁月真是令人难以置信。如果有人有想法不添加10行代码,请继续发布,以便将其添加到我的代码中。

纪元:我没有考虑时间,因为需要删除早于某个特定日期的文件,如果花费数小时/分钟,就会删除本来要保存的日期的文件。

局限性

纪元理所当然的,短日期格式为YYYY-MM-DD。需要将其调整为其他设置或者运行时评估(读取sShortTime,用户绑定配置,在过滤器中配置适当的字段顺序并使用过滤器从参数中提取正确的数据)。

我是否提到我讨厌该编辑器的自动格式化?它删除了空白行,并且复制粘贴是一个地狱。

我希望这有帮助。

回答

看看我对类似问题的回答:

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"

这将删除早于给定日期的文件。我确定可以将其修改为从当前日期返回7天。

更新:我注意到HerbCSO在上述脚本上有所改进。我建议改用他的版本。

回答

考虑到a年,对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.贡献的上述条件总是评估为false。

" GEQ第2个月"也是错误的,因为必须在a年(仅在3月到12月的月份而不是2月的月份)再增加86400秒的一天。

Jay发布的批处理文件7daysclean.cmd中仅在当年考虑leap日的工作代码为:

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

回答

如果我们拥有XP资源工具包,则可以使用robocopy将所有旧目录移动到一个目录中,然后使用rmdir删除该目录:

mkdir c:\temp\OldDirectoriesGoHere
robocopy c:\logs\SoManyDirectoriesToDelete\ c:\temp\OldDirectoriesGoHere\ /move /minage:7
rmdir /s /q c:\temp\OldDirectoriesGoHere

回答

我的命令是

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

在我的情况下,@ PATH只是路径,所以我不得不使用@PATH \ @ FILE

forfiles /?也不适合我,但是forfiles(不带"?")也可以。

我唯一的问题是:如何添加多个掩码(例如" .log | .bak")?

我在此处下载的所有与forfiles.exe有关的文件(在Win XP上)

但是,如果我们使用Windows服务器,则forfiles.exe应该已经存在,并且与ftp版本不同。这就是为什么我应该修改命令。

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

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