我正在寻找一种方法来删除批处理文件中超过7天的所有文件。我在网上搜索了一下,找到了一些包含数百行代码的示例,还有一些示例需要安装额外的命令行实用程序来完成任务。
在BASH中,只需几行代码就可以完成类似的工作。在Windows中,似乎可以为批处理文件做一些简单的事情。我正在寻找一个解决方案,工作在标准的Windows命令提示符,没有任何额外的实用程序。请不要使用PowerShell或Cygwin。
我正在寻找一种方法来删除批处理文件中超过7天的所有文件。我在网上搜索了一下,找到了一些包含数百行代码的示例,还有一些示例需要安装额外的命令行实用程序来完成任务。
在BASH中,只需几行代码就可以完成类似的工作。在Windows中,似乎可以为批处理文件做一些简单的事情。我正在寻找一个解决方案,工作在标准的Windows命令提示符,没有任何额外的实用程序。请不要使用PowerShell或Cygwin。
当前回答
在我看来,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开始的总天数(之后返回负年份)。
注意:数学只是单向的;它不能从负输入中正确地获得未来的日期(它会尝试,但可能会超过本月的最后一天)。
在我看来,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文件,并清理子文件夹。
我的脚本删除文件早于特定年份:
@REM _______ GENERATE A CMD TO DELETE FILES OLDER THAN A GIVEN YEAR
@REM _______ (given in _olderthanyear variable)
@REM _______ (you must LOCALIZE the script depending on the dir cmd console output)
@REM _______ (we assume here the following line's format "11/06/2017 15:04 58 389 SpeechToText.zip")
@set _targetdir=c:\temp
@set _olderthanyear=2017
@set _outfile1="%temp%\deleteoldfiles.1.tmp.txt"
@set _outfile2="%temp%\deleteoldfiles.2.tmp.txt"
@if not exist "%_targetdir%" (call :process_error 1 DIR_NOT_FOUND "%_targetdir%") & (goto :end)
:main
@dir /a-d-h-s /s /b %_targetdir%\*>%_outfile1%
@for /F "tokens=*" %%F in ('type %_outfile1%') do @call :process_file_path "%%F" %_outfile2%
@goto :end
:end
@rem ___ cleanup and exit
@if exist %_outfile1% del %_outfile1%
@if exist %_outfile2% del %_outfile2%
@goto :eof
:process_file_path %1 %2
@rem ___ get date info of the %1 file path
@dir %1 | find "/" | find ":" > %2
@for /F "tokens=*" %%L in ('type %2') do @call :process_line "%%L" %1
@goto :eof
:process_line %1 %2
@rem ___ generate a del command for each file older than %_olderthanyear%
@set _var=%1
@rem LOCALIZE HERE (char-offset,string-length)
@set _fileyear=%_var:~0,4%
@set _fileyear=%_var:~7,4%
@set _filepath=%2
@if %_fileyear% LSS %_olderthanyear% echo @REM %_fileyear%
@if %_fileyear% LSS %_olderthanyear% echo @del %_filepath%
@goto :eof
:process_error %1 %2
@echo RC=%1 MSG=%2 %3
@goto :eof
天啊,已经有很多答案了。我发现的一个简单而方便的方法是使用&参数从单个Windows命令行指令连续执行两次ROBOCOPY.EXE。
ROBOCOPY.EXE SOURCE-DIR TARGET-DIR *.* /MOV /MINAGE:30 & ROBOCOPY.EXE SOURCE-DIR TARGET-DIR *.* /MOV /MINAGE:30 /PURGE
在这个例子中,它的工作原理是选择所有超过30天的文件(.)并将它们移动到目标文件夹。第二个命令再次执行相同的操作,添加了PURGE命令,这意味着删除目标文件夹中不存在于源文件夹中的文件。 因此,从本质上讲,第一个命令移动文件,第二个命令删除文件,因为当调用第二个命令时,它们不再存在于源文件夹中。
在测试时,请参考ROBOCOPY的文档并使用/L开关。
享受:
forfiles -p "C:\what\ever" -s -m *.* -d <number of days> -c "cmd /c del @path"
更多细节请参见forfiles文档。
要了解更多信息,请参考Windows XP命令行的A-Z索引。
如果您的计算机上没有安装forfiles,请将其从任何Windows Server 2003复制到您的Windows XP计算机的%WinDir%\system32\。这是可能的,因为EXE在Windows Server 2003和Windows XP之间完全兼容。
后续版本的Windows和Windows Server默认安装了它。
Windows 7及更新版本(包括Windows 10):
语法略有变化。因此更新后的命令为:
forfiles /p "C:\what\ever" /s /m *.* /D -<number of days> /C "cmd /c del @path"