我正在寻找一种方法来删除批处理文件中超过7天的所有文件。我在网上搜索了一下,找到了一些包含数百行代码的示例,还有一些示例需要安装额外的命令行实用程序来完成任务。
在BASH中,只需几行代码就可以完成类似的工作。在Windows中,似乎可以为批处理文件做一些简单的事情。我正在寻找一个解决方案,工作在标准的Windows命令提示符,没有任何额外的实用程序。请不要使用PowerShell或Cygwin。
我正在寻找一种方法来删除批处理文件中超过7天的所有文件。我在网上搜索了一下,找到了一些包含数百行代码的示例,还有一些示例需要安装额外的命令行实用程序来完成任务。
在BASH中,只需几行代码就可以完成类似的工作。在Windows中,似乎可以为批处理文件做一些简单的事情。我正在寻找一个解决方案,工作在标准的Windows命令提示符,没有任何额外的实用程序。请不要使用PowerShell或Cygwin。
当前回答
这一个帮我做到了。它有一个日期,你可以减去想要的数量,回到过去的时间:
@echo off
set m=%date:~-7,2%
set /A m
set dateYear=%date:~-4,4%
set /A dateYear -= 2
set DATE_DIR=%date:~-10,2%.%m%.%dateYear%
forfiles /p "C:\your\path\here\" /s /m *.* /d -%DATE_DIR% /c "cmd /c del @path /F"
pause
cmd /c del @path /F中的/F强制删除特定文件,在某些情况下,该文件可以是只读的。
dateYear是年份变量,您可以根据自己的需要更改减号
其他回答
在我看来,JavaScript正在逐渐成为一种通用的脚本标准:它可能比任何其他脚本语言都适用于更多的产品(在Windows中,可以使用Windows脚本主机)。我必须清理旧文件在很多文件夹,所以这里是一个JavaScript函数来做:
// run from an administrator command prompt (or from task scheduler with full rights): wscript jscript.js
// debug with: wscript /d /x jscript.js
var fs = WScript.CreateObject("Scripting.FileSystemObject");
clearFolder('C:\\temp\\cleanup');
function clearFolder(folderPath)
{
// calculate date 3 days ago
var dateNow = new Date();
var dateTest = new Date();
dateTest.setDate(dateNow.getDate() - 3);
var folder = fs.GetFolder(folderPath);
var files = folder.Files;
for( var it = new Enumerator(files); !it.atEnd(); it.moveNext() )
{
var file = it.item();
if( file.DateLastModified < dateTest)
{
var filename = file.name;
var ext = filename.split('.').pop().toLowerCase();
if (ext != 'exe' && ext != 'dll')
{
file.Delete(true);
}
}
}
var subfolders = new Enumerator(folder.SubFolders);
for (; !subfolders.atEnd(); subfolders.moveNext())
{
clearFolder(subfolders.item().Path);
}
}
对于每个要清除的文件夹,只需要对clearFolder()函数添加另一个调用。这个特定的代码还保存exe和dll文件,并清理子文件夹。
我认为e.James的答案很好,因为它适用于早于Windows 2000 SP4(可能更早)的未修改版本的Windows,但它需要写入外部文件。下面是一个修改后的版本,在保持兼容性的同时不创建外部文本文件:
REM del_old.cmd
REM usage: del_old MM-DD-YYYY
setlocal enabledelayedexpansion
for /f "tokens=*" %%a IN ('xcopy *.* /d:%1 /L /I null') do @if exist "%%~nxa" set "excludefiles=!excludefiles!;;%%~nxa;;"
for /f "tokens=*" %%a IN ('dir /b') do @(@echo "%excludefiles%"|FINDSTR /C:";;%%a;;">nul || if exist "%%~nxa" DEL /F /Q "%%a">nul 2>&1)
为了忠于最初的问题,如果你用天数作为参数调用它,它在一个脚本中为你做了所有的数学运算:
REM del_old_compute.cmd
REM usage: del_old_compute N
setlocal enabledelayedexpansion
set /a days=%1&set cur_y=%DATE:~10,4%&set cur_m=%DATE:~4,2%&set cur_d=%DATE:~7,2%
for /f "tokens=1 delims==" %%a in ('set cur_') do if "!%%a:~0,1!"=="0" set /a %%a=!%%a:~1,1!+0
set mo_2=28&set /a leapyear=cur_y*10/4
if %leapyear:~-1% equ 0 set mo_2=29
set mo_1=31&set mo_3=31&set mo_4=30&set mo_5=31
set mo_6=30&set mo_7=31&set mo_8=31&set mo_9=30
set mo_10=31&set mo_11=30&set mo_12=31
set /a past_y=(days/365)
set /a monthdays=days-((past_y*365)+((past_y/4)*1))&&set /a past_y=cur_y-past_y&set months=0
:setmonth
set /a minusmonth=(cur_m-1)-months
if %minusmonth% leq 0 set /a minusmonth+=12
set /a checkdays=(mo_%minusmonth%)
if %monthdays% geq %checkdays% set /a months+=1&set /a monthdays-=checkdays&goto :setmonth
set /a past_m=cur_m-months
set /a lastmonth=cur_m-1
if %lastmonth% leq 0 set /a lastmonth+=12
set /a lastmonth=mo_%lastmonth%
set /a past_d=cur_d-monthdays&set adddays=::
if %past_d% leq 0 (set /a past_m-=1&set adddays=)
if %past_m% leq 0 (set /a past_m+=12&set /a past_y-=1)
set mo_2=28&set /a leapyear=past_y*10/4
if %leapyear:~-1% equ 0 set mo_2=29
%adddays%set /a past_d+=mo_%past_m%
set d=%past_m%-%past_d%-%past_y%
for /f "tokens=*" %%a IN ('xcopy *.* /d:%d% /L /I null') do @if exist "%%~nxa" set "excludefiles=!excludefiles!;;%%~nxa;;"
for /f "tokens=*" %%a IN ('dir /b') do @(@echo "%excludefiles%"|FINDSTR /C:";;%%a;;">nul || if exist "%%~nxa" DEL /F /Q "%%a">nul 2>&1)
注意:上面的代码考虑了闰年,以及每个月的确切天数。唯一的最大值是从0/0/0开始的总天数(之后返回负年份)。
注意:数学只是单向的;它不能从负输入中正确地获得未来的日期(它会尝试,但可能会超过本月的最后一天)。
对于windows 2012 R2,以下将工作:
forfiles /p "c:\FOLDERpath" /d -30 /c "cmd /c del @path"
要查看将要删除的文件,请使用此命令
forfiles /p "c:\FOLDERpath" /d -30 /c "cmd /c echo @path @fdate"
看看我对类似问题的回答:
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已经改进了上面的脚本。我建议改用他的版本。
Ok有点无聊,想出了这个,它包含了我的版本,一个穷人的Linux纪元替代品,仅限于日常使用(没有时间保留):
7 daysclean.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
使用
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行代码的想法,请继续发表,这样我就可以把它添加到我的代码中。
epoch:我没有考虑到时间,因为需要删除超过某个日期的文件,花几个小时/分钟就会删除一天的文件,这意味着要保存。
限制
epoch认为你的短日期格式是YYYY-MM-DD。它需要适应其他设置或运行时计算(读取sShortTime,用户绑定配置,在过滤器中配置正确的字段顺序,并使用过滤器从参数中提取正确的数据)。
我说过我讨厌这个编辑器的自动格式化吗?它删除了空白行,复制粘贴是一个地狱。
我希望这能有所帮助。