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

在BASH中,只需几行代码就可以完成类似的工作。在Windows中,似乎可以为批处理文件做一些简单的事情。我正在寻找一个解决方案,工作在标准的Windows命令提示符,没有任何额外的实用程序。请不要使用PowerShell或Cygwin。


当前回答

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

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

其他回答

天啊,已经有很多答案了。我发现的一个简单而方便的方法是使用&参数从单个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开关。

复制这段代码并保存为DelOldFiles.vbs。

使用CMD: cscript //nologo DelOldFiles。于六月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

在我看来,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文件,并清理子文件夹。

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,用户绑定配置,在过滤器中配置正确的字段顺序,并使用过滤器从参数中提取正确的数据)。

我说过我讨厌这个编辑器的自动格式化吗?它删除了空白行,复制粘贴是一个地狱。

我希望这能有所帮助。

我的脚本删除文件早于特定年份:

@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