<p>I am looking for a way to delete all files older than 7 days in a batch file.  I've searched around the web, and found some examples with hundreds of lines of code, and others that required installing extra command line utilities to accomplish the task.</p>

<p>Similar things can be <a href="https://stackoverflow.com/questions/25785/delete-all-but-the-most-recent-x-files-in-bash">done in BASH</a> in just a couple lines of code. It seems that something at least remotely easy could be done for batch files in Windows. I'm looking for a solution that works in a standard Windows command prompt, without any extra utilities. Please no PowerShell or Cygwin either.</p>

[{'answer_id': 51069, 'author': 'aku', 'author_id': 1196, 'author_profile': 'https://Stackoverflow.com/users/1196', 'pm_score': 11, 'selected': True, 'text': '<p>Enjoy:</p>\n\n<pre><code>forfiles -p "C:\\what\\ever" -s -m *.* -d &lt;number of days&gt; -c "cmd /c del @path"\n</code></pre>\n\n<p>See <a href="http://ss64.com/nt/forfiles.html" rel="noreferrer"><code>forfiles</code> documentation</a> for more details.</p>\n\n<p>For more goodies, refer to <em><a href="http://www.ss64.com/nt/" rel="noreferrer">An A-Z Index of the Windows&nbsp;XP command line</a></em>.</p>\n\n<p>If you don\'t have <code>forfiles</code> installed on your machine, copy it from any <a href="http://en.wikipedia.org/wiki/Windows_Server_2003" rel="noreferrer">Windows&nbsp;Server&nbsp;2003</a> to your Windows&nbsp;XP machine at <code>%WinDir%\\system32\\</code>. This is possible since the EXE is fully compatible between Windows&nbsp;Server&nbsp;2003 and Windows&nbsp;XP.</p>\n\n<p>Later versions of Windows and Windows&nbsp;Server have it installed by default.</p>\n\n<p>For Windows&nbsp;7 and newer (including Windows&nbsp;10):</p>\n\n<p>The syntax has changed a little. Therefore the updated command is:</p>\n\n<pre><code>forfiles /p "C:\\what\\ever" /s /m *.* /D -&lt;number of days&gt; /C "cmd /c del @path"\n</code></pre>\n'}, {'answer_id': 52003, 'author': 'Paulius', 'author_id': 1353085, 'author_profile': 'https://Stackoverflow.com/users/1353085', 'pm_score': 2, 'selected': False, 'text': '<p>You might be able to pull this off. You can take a look at <a href="https://stackoverflow.com/questions/51837/open-one-of-a-series-of-files-using-a-batch-file">this question</a>, for a simpler example. The complexity comes, when you start comparing the dates. It may be easy to tell if the date is greater or not, but there are many situations to consider if you need to actually get the difference between two dates.</p>\n\n<p>In other words - don\'t try to invent this, unless you really can\'t use the third party tools.</p>\n'}, {'answer_id': 1322886, 'author': 'Jay', 'author_id': 151152, 'author_profile': 'https://Stackoverflow.com/users/151152', 'pm_score': 5, 'selected': False, 'text': '<p>Ok was bored a bit and came up with this, which contains my version of a poor man\'s Linux epoch replacement limited for daily usage (no time retention):</p>\n\n<p>7daysclean.cmd</p>\n\n<pre><code>@echo off\nsetlocal ENABLEDELAYEDEXPANSION\nset day=86400\nset /a year=day*365\nset /a strip=day*7\nset dSource=C:\\temp\n\ncall :epoch %date%\nset /a slice=epoch-strip\n\nfor /f "delims=" %%f in (\'dir /a-d-h-s /b /s %dSource%\') do (\n    call :epoch %%~tf\n    if !epoch! LEQ %slice% (echo DELETE %%f ^(%%~tf^)) ELSE echo keep %%f ^(%%~tf^)\n)\nexit /b 0\n\nrem Args[1]: Year-Month-Day\n:epoch\n    setlocal ENABLEDELAYEDEXPANSION\n    for /f "tokens=1,2,3 delims=-" %%d in (\'echo %1\') do set Years=%%d&amp; set Months=%%e&amp; set Days=%%f\n    if "!Months:~0,1!"=="0" set Months=!Months:~1,1!\n    if "!Days:~0,1!"=="0" set Days=!Days:~1,1!\n    set /a Days=Days*day\n    set /a _months=0\n    set i=1&amp;&amp; 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&amp;&amp; set /a i+=1)\n    set /a Months=!_months!\n    set /a Years=(Years-1970)*year\n    set /a Epoch=Years+Months+Days\n    endlocal&amp; set Epoch=%Epoch%\n    exit /b 0\n</code></pre>\n\n<h2>USAGE</h2>\n\n<p><code>set /a strip=day*7</code> : Change <strong>7</strong> for the number of days to keep.</p>\n\n<p><code>set dSource=C:\\temp</code> : This is the starting directory to check for files.</p>\n\n<h2>NOTES</h2>\n\n<p>This is non-destructive code, it will display what would have happened.</p>\n\n<p>Change :</p>\n\n<pre><code>if !epoch! LEQ %slice% (echo DELETE %%f ^(%%~tf^)) ELSE echo keep %%f ^(%%~tf^)\n</code></pre>\n\n<p>to something like :</p>\n\n<pre><code>if !epoch! LEQ %slice% del /f %%f\n</code></pre>\n\n<p>so files actually get deleted</p>\n\n<p><strong>February</strong>: is hard-coded to 28 days. Bissextile years is a hell to add, really. if someone has an idea that would not add 10 lines of code, go ahead and post so I add it to my code.</p>\n\n<p><strong>epoch</strong>: I did not take time into consideration, as the need is to delete files older than a certain date, taking hours/minutes would have deleted files from a day that was meant for keeping.</p>\n\n<h2>LIMITATION</h2>\n\n<p><strong>epoch</strong> takes for granted your short date format is YYYY-MM-DD.  It would need to be adapted for other settings or a run-time evaluation (read sShortTime, user-bound configuration, configure proper field order in a filter and use the filter to extract the correct data from the argument).</p>\n\n<p>Did I mention I hate this editor\'s auto-formating? it removes the blank lines and the copy-paste is a hell.</p>\n\n<p>I hope this helps.</p>\n'}, {'answer_id': 1322976, 'author': 'e.James', 'author_id': 33686, 'author_profile': 'https://Stackoverflow.com/users/33686', 'pm_score': 4, 'selected': False, 'text': '<p>Have a look at my <a href="https://stackoverflow.com/questions/324267/batch-file-to-delete-files-older-than-a-specified-date/324349#324349">answer</a> to a <a href="https://stackoverflow.com/questions/324267/batch-file-to-delete-files-older-than-a-specified-date">similar question</a>:</p>\n\n<pre><code>REM del_old.bat\nREM usage: del_old MM-DD-YYY\nfor /f "tokens=*" %%a IN (\'xcopy *.* /d:%1 /L /I null\') do if exist %%~nxa echo %%~nxa &gt;&gt; FILES_TO_KEEP.TXT\nfor /f "tokens=*" %%a IN (\'xcopy *.* /L /I /EXCLUDE:FILES_TO_KEEP.TXT null\') do if exist "%%~nxa" del "%%~nxa"\n</code></pre>\n\n<p>This deletes files older than a given date. I\'m sure it can be modified to go back seven days from the current date.</p>\n\n<p><strong>update:</strong> I notice that HerbCSO has improved on the above script. I recommend using <a href="https://stackoverflow.com/questions/324267/batch-file-to-delete-files-older-than-a-specified-date/1180746#1180746">his version</a> instead.</p>\n'}, {'answer_id': 3161104, 'author': 'J.R.', 'author_id': 381472, 'author_profile': 'https://Stackoverflow.com/users/381472', 'pm_score': 3, 'selected': False, 'text': '<p>How about this modification on <a href="https://stackoverflow.com/a/1322886/3074564">7daysclean.cmd</a> to take a leap year into account?</p>\n\n<p>It can be done in less than 10 lines of coding!</p>\n\n<pre><code>set /a Leap=0\nif (Month GEQ 2 and ((Years%4 EQL 0 and Years%100 NEQ 0) or Years%400 EQL 0)) set /a Leap=day\nset /a Months=!_months!+Leap\n</code></pre>\n\n<hr>\n\n<p><strong>Edit by Mofi:</strong></p>\n\n<p>The condition above contributed by <a href="https://stackoverflow.com/users/381472/j-r">J.R.</a> evaluates always to <strong>false</strong> because of invalid syntax.</p>\n\n<p>And <code>Month GEQ 2</code> is also wrong because adding 86400 seconds for one more day must be done in a leap year only for the months March to December, but not for February.</p>\n\n<p>A working code to take leap day into account - in current year only - in batch file <strong>7daysclean.cmd</strong> posted by <a href="https://stackoverflow.com/users/151152/jay">Jay</a> would be:</p>\n\n<pre><code>set "LeapDaySecs=0"\nif %Month% LEQ 2 goto CalcMonths\nset /a "LeapRule=Years%%4"\nif %LeapRule% NEQ 0 goto CalcMonths\nrem The other 2 rules can be ignored up to year 2100.\nset /A "LeapDaySecs=day"\n:CalcMonths\nset /a Months=!_months!+LeapDaySecs\n</code></pre>\n'}, {'answer_id': 4383245, 'author': 'neuracnu', 'author_id': 19277, 'author_profile': 'https://Stackoverflow.com/users/19277', 'pm_score': 2, 'selected': False, 'text': '<p>If you have the XP resource kit, you can use robocopy to move all the old directories into a single directory, then use rmdir to delete just that one:</p>\n\n<pre><code>mkdir c:\\temp\\OldDirectoriesGoHere\nrobocopy c:\\logs\\SoManyDirectoriesToDelete\\ c:\\temp\\OldDirectoriesGoHere\\ /move /minage:7\nrmdir /s /q c:\\temp\\OldDirectoriesGoHere\n</code></pre>\n'}, {'answer_id': 4436614, 'author': 'segero', 'author_id': 551504, 'author_profile': 'https://Stackoverflow.com/users/551504', 'pm_score': 4, 'selected': False, 'text': '<p>My command is</p>\n\n<pre><code>forfiles -p "d:\\logs" -s -m*.log -d-15 -c"cmd /c del @PATH\\@FILE" \n</code></pre>\n\n<p><code>@PATH</code> - is just path in my case, so I had to use <code>@PATH\\@FILE</code></p>\n\n<p>also <code>forfiles /?</code> not working for me too, but <code>forfiles</code> (without "?") worked fine.</p>\n\n<p>And the only question I have: how to add multiple mask (for example "<em>.log|</em>.bak")?</p>\n\n<p>All this regarding forfiles.exe that I <a href="ftp://ftp.microsoft.com/ResKit/y2kfix/x86/" rel="noreferrer">downloaded here</a> (on win XP)</p>\n\n<p>But if you are using Windows server forfiles.exe should be already there and it is differs from ftp version. That is why I should modify command. </p>\n\n<p>For Windows Server 2003 I\'m using this command:</p>\n\n<pre><code>forfiles -p "d:\\Backup" -s -m *.log -d -15 -c "cmd /c del @PATH"\n</code></pre>\n'}, {'answer_id': 4800680, 'author': 'Paris', 'author_id': 589995, 'author_profile': 'https://Stackoverflow.com/users/589995', 'pm_score': 3, 'selected': False, 'text': '<p>Copy this code and save it as <code>DelOldFiles.vbs</code>.</p>\n\n<p>USAGE IN CMD  : <code>cscript //nologo DelOldFiles.vbs 15</code></p>\n\n<p>15 means to delete files older than 15 days in past.</p>\n\n<pre><code>  \'copy from here\n    Function DeleteOlderFiles(whichfolder)\n       Dim fso, f, f1, fc, n, ThresholdDate\n       Set fso = CreateObject("Scripting.FileSystemObject")\n       Set f = fso.GetFolder(whichfolder)\n       Set fc = f.Files\n       Set objArgs = WScript.Arguments\n       n = 0\n       If objArgs.Count=0 Then\n           howmuchdaysinpast = 0\n       Else\n           howmuchdaysinpast = -objArgs(0)\n       End If\n       ThresholdDate = DateAdd("d", howmuchdaysinpast, Date)   \n       For Each f1 in fc\n     If f1.DateLastModified&lt;ThresholdDate Then\n        Wscript.StdOut.WriteLine f1\n        f1.Delete\n        n = n + 1    \n     End If\n       Next\n       Wscript.StdOut.WriteLine "Deleted " &amp; n &amp; " file(s)."\n    End Function\n\n    If Not WScript.FullName = WScript.Path &amp; "\\cscript.exe" Then\n      WScript.Echo "USAGE ONLY IN COMMAND PROMPT: cscript DelOldFiles.vbs 15" &amp; vbCrLf &amp; "15 means to delete files older than 15 days in past."\n      WScript.Quit 0   \n    End If\n\n    DeleteOlderFiles(".")\n \'to here\n</code></pre>\n'}, {'answer_id': 6149776, 'author': 'Iman', 'author_id': 772718, 'author_profile': 'https://Stackoverflow.com/users/772718', 'pm_score': 6, 'selected': False, 'text': '<p>Run the following <a href="https://technet.microsoft.com/en-us/library/cc733145.aspx" rel="noreferrer">commands</a>:</p>\n\n<pre><code>ROBOCOPY C:\\source C:\\destination /mov /minage:7\ndel C:\\destination /q\n</code></pre>\n\n<p>Move all the files (using /mov, which moves files and then deletes them as opposed to /move which moves whole filetrees which are then deleted) via robocopy to another location, and then execute a delete command on that path and you\'re all good.  </p>\n\n<p>Also if you have a directory with lots of data in it you can use <code>/mir</code> switch </p>\n'}, {'answer_id': 6275689, 'author': 'Arno Jansen', 'author_id': 788773, 'author_profile': 'https://Stackoverflow.com/users/788773', 'pm_score': 5, 'selected': False, 'text': '<pre><code>forfiles /p "v:" /s /m *.* /d -3 /c "cmd /c del @path"\n</code></pre>\n\n<p>You should do <code>/d -3</code> (3 days earlier) This works fine for me. So all the complicated batches could be in the trash bin. Also <code>forfiles</code> don\'t support UNC paths, so make a network connection to a specific drive.</p>\n'}, {'answer_id': 8123408, 'author': 'Aidan Ewen', 'author_id': 795896, 'author_profile': 'https://Stackoverflow.com/users/795896', 'pm_score': 3, 'selected': False, 'text': '<p>Use forfiles. </p>\n\n<p>There are different versions. Early ones use unix style parameters. </p>\n\n<p>My version (for server 2000 - note no space after switches)- </p>\n\n<pre><code>forfiles -p"C:\\what\\ever" -s -m*.* -d&lt;number of days&gt; -c"cmd /c del @path"\n</code></pre>\n\n<p>To add forfiles to XP, get the exe from <a href="ftp://ftp.microsoft.com/ResKit/y2kfix/x86/" rel="noreferrer">ftp://ftp.microsoft.com/ResKit/y2kfix/x86/</a></p>\n\n<p>and add it to C:\\WINDOWS\\system32</p>\n'}, {'answer_id': 10358807, 'author': 'NotJustClarkKent', 'author_id': 334695, 'author_profile': 'https://Stackoverflow.com/users/334695', 'pm_score': 3, 'selected': False, 'text': '<p>For Windows Server 2008 R2:</p>\n\n<pre><code>forfiles /P c:\\sql_backups\\ /S /M *.sql /D -90 /C "cmd /c del @PATH"\n</code></pre>\n\n<p>This will delete all <em>.sql</em> files older than <em>90</em> days.</p>\n'}, {'answer_id': 16234804, 'author': 'Graham Laight', 'author_id': 1649135, 'author_profile': 'https://Stackoverflow.com/users/1649135', 'pm_score': 3, 'selected': False, 'text': '<p>IMO, JavaScript is gradually becoming a universal scripting standard: it is probably available in more products than any other scripting language (in Windows, it is available using the Windows Scripting Host). I have to clean out old files in lots of folders, so here is a JavaScript function to do that:</p>\n\n<pre><code>// run from an administrator command prompt (or from task scheduler with full rights):  wscript jscript.js\n// debug with:   wscript /d /x jscript.js\n\nvar fs = WScript.CreateObject("Scripting.FileSystemObject");\n\nclearFolder(\'C:\\\\temp\\\\cleanup\');\n\nfunction clearFolder(folderPath)\n{\n    // calculate date 3 days ago\n    var dateNow = new Date();\n    var dateTest = new Date();\n    dateTest.setDate(dateNow.getDate() - 3);\n\n    var folder = fs.GetFolder(folderPath);\n    var files = folder.Files;\n\n    for( var it = new Enumerator(files); !it.atEnd(); it.moveNext() )\n    {\n        var file = it.item();\n\n        if( file.DateLastModified &lt; dateTest)\n        {\n            var filename = file.name;\n            var ext = filename.split(\'.\').pop().toLowerCase();\n\n            if (ext != \'exe\' &amp;&amp; ext != \'dll\')\n            {\n                file.Delete(true);\n            }\n        }\n    }\n\n    var subfolders = new Enumerator(folder.SubFolders);\n    for (; !subfolders.atEnd(); subfolders.moveNext())\n    {\n        clearFolder(subfolders.item().Path);\n    }\n}\n</code></pre>\n\n<p>For each folder to clear, just add another call to the clearFolder() function. This particular code also preserves exe and dll files, and cleans up subfolders as well.</p>\n'}, {'answer_id': 20671056, 'author': 'Goran B.', 'author_id': 2175524, 'author_profile': 'https://Stackoverflow.com/users/2175524', 'pm_score': 2, 'selected': False, 'text': '<p>this is nothing amazing, but i needed to do something like this today and run it as scheduled task etc.</p>\n\n<p>batch file, DelFilesOlderThanNDays.bat below with sample exec w/ params:</p>\n\n<blockquote>\n  <p>DelFilesOlderThanNDays.bat <strong>7</strong> <em>C:\\dir1\\dir2\\dir3\\logs</em> <strong>*.log</strong></p>\n</blockquote>\n\n<pre><code>echo off\ncls\nEcho(\nSET keepDD=%1\nSET logPath=%2 :: example C:\\dir1\\dir2\\dir3\\logs\nSET logFileExt=%3\nSET check=0\nIF [%3] EQU [] SET logFileExt=*.log &amp; echo: file extention not specified (default set to "*.log")\nIF [%2] EQU [] echo: file directory no specified (a required parameter), exiting! &amp; EXIT /B \nIF [%1] EQU [] echo: number of days not specified? :)\necho(\necho: in path [ %logPath% ]\necho: finding all files like [ %logFileExt% ]\necho: older than [ %keepDD% ] days\necho(\n::\n::\n:: LOG\necho:  &gt;&gt; c:\\trimLogFiles\\logBat\\log.txt\necho: executed on %DATE% %TIME% &gt;&gt; c:\\trimLogFiles\\logBat\\log.txt\necho: ---------------------------------------------------------- &gt;&gt; c:\\trimLogFiles\\logBat\\log.txt\necho: in path [ %logPath% ] &gt;&gt; c:\\trimLogFiles\\logBat\\log.txt\necho: finding all files like [ %logFileExt% ] &gt;&gt; c:\\trimLogFiles\\logBat\\log.txt\necho: older than [ %keepDD% ] days &gt;&gt; c:\\trimLogFiles\\logBat\\log.txt\necho: ---------------------------------------------------------- &gt;&gt; c:\\trimLogFiles\\logBat\\log.txt\n::\nFORFILES /p %logPath% /s /m %logFileExt% /d -%keepDD% /c "cmd /c echo @path" &gt;&gt; c:\\trimLogFiles\\logBat\\log.txt 2&lt;&amp;1\nIF %ERRORLEVEL% EQU 0 (\n FORFILES /p %logPath% /s /m %logFileExt% /d -%keepDD% /c "cmd /c echo @path"\n)\n::\n::\n:: LOG\nIF %ERRORLEVEL% EQU 0 (\n echo:  &gt;&gt; c:\\trimLogFiles\\logBat\\log.txt\n echo: deleting files ... &gt;&gt; c:\\trimLogFiles\\logBat\\log.txt\n echo:  &gt;&gt; c:\\trimLogFiles\\logBat\\log.txt\n SET check=1\n)\n::\n::\nIF %check% EQU 1 (\n FORFILES /p %logPath% /s /m %logFileExt% /d -%keepDD% /c "cmd /c del @path"\n)\n::\n:: RETURN &amp; LOG\n::\nIF %ERRORLEVEL% EQU 0 echo: deletion successfull! &amp; echo: deletion successfull! &gt;&gt; c:\\trimLogFiles\\logBat\\log.txt\necho: ---------------------------------------------------------- &gt;&gt; c:\\trimLogFiles\\logBat\\log.txt\n</code></pre>\n'}, {'answer_id': 20893589, 'author': 'Lectrode', 'author_id': 1284754, 'author_profile': 'https://Stackoverflow.com/users/1284754', 'pm_score': 2, 'selected': False, 'text': '<p>I think <a href="https://stackoverflow.com/a/1322976/1284754">e.James\'s answer</a> is good since it works with unmodified versions of Windows as early as Windows 2000 SP4 (and possibly earlier), but it required writing to an external file. Here is a modified version that does not create an external text file while maintaining the compatibility:</p>\n\n<pre><code>REM del_old.cmd\nREM usage: del_old MM-DD-YYYY\nsetlocal enabledelayedexpansion\nfor /f "tokens=*" %%a IN (\'xcopy *.* /d:%1 /L /I null\') do @if exist "%%~nxa" set "excludefiles=!excludefiles!;;%%~nxa;;"\nfor /f "tokens=*" %%a IN (\'dir /b\') do @(@echo "%excludefiles%"|FINDSTR /C:";;%%a;;"&gt;nul || if exist "%%~nxa" DEL /F /Q "%%a"&gt;nul 2&gt;&amp;1)\n</code></pre>\n\n<p>To be true to the original question, here it is in a script that does ALL the math for you if you call it with the number of days as the parameter:</p>\n\n<pre><code>REM del_old_compute.cmd\nREM usage: del_old_compute N\nsetlocal enabledelayedexpansion\nset /a days=%1&amp;set cur_y=%DATE:~10,4%&amp;set cur_m=%DATE:~4,2%&amp;set cur_d=%DATE:~7,2%\nfor /f "tokens=1 delims==" %%a in (\'set cur_\') do if "!%%a:~0,1!"=="0" set /a %%a=!%%a:~1,1!+0\nset mo_2=28&amp;set /a leapyear=cur_y*10/4\nif %leapyear:~-1% equ 0 set mo_2=29\nset mo_1=31&amp;set mo_3=31&amp;set mo_4=30&amp;set mo_5=31\nset mo_6=30&amp;set mo_7=31&amp;set mo_8=31&amp;set mo_9=30\nset mo_10=31&amp;set mo_11=30&amp;set mo_12=31\nset /a past_y=(days/365)\nset /a monthdays=days-((past_y*365)+((past_y/4)*1))&amp;&amp;set /a past_y=cur_y-past_y&amp;set months=0\n:setmonth\nset /a minusmonth=(cur_m-1)-months\nif %minusmonth% leq 0 set /a minusmonth+=12\nset /a checkdays=(mo_%minusmonth%)\nif %monthdays% geq %checkdays% set /a months+=1&amp;set /a monthdays-=checkdays&amp;goto :setmonth\nset /a past_m=cur_m-months\nset /a lastmonth=cur_m-1\nif %lastmonth% leq 0 set /a lastmonth+=12\nset /a lastmonth=mo_%lastmonth%\nset /a past_d=cur_d-monthdays&amp;set adddays=::\nif %past_d% leq 0 (set /a past_m-=1&amp;set adddays=)\nif %past_m% leq 0 (set /a past_m+=12&amp;set /a past_y-=1)\nset mo_2=28&amp;set /a leapyear=past_y*10/4\nif %leapyear:~-1% equ 0 set mo_2=29\n%adddays%set /a past_d+=mo_%past_m%\nset d=%past_m%-%past_d%-%past_y%\nfor /f "tokens=*" %%a IN (\'xcopy *.* /d:%d% /L /I null\') do @if exist "%%~nxa" set "excludefiles=!excludefiles!;;%%~nxa;;"\nfor /f "tokens=*" %%a IN (\'dir /b\') do @(@echo "%excludefiles%"|FINDSTR /C:";;%%a;;"&gt;nul || if exist "%%~nxa" DEL /F /Q "%%a"&gt;nul 2&gt;&amp;1)\n</code></pre>\n\n<p>NOTE: The code above takes into account leap years, as well as the exact number of days in each month. The only maximum is the total number of days there have been since 0/0/0 (after that it returns negative years).</p>\n\n<p>NOTE: The math only goes one way; it cannot correctly get future dates from negative input (it will try, but will likely go past the last day of the month).</p>\n'}, {'answer_id': 22401809, 'author': 'Tobias Järvelöv', 'author_id': 1141914, 'author_profile': 'https://Stackoverflow.com/users/1141914', 'pm_score': 2, 'selected': False, 'text': '<p>Expanding on aku\'s answer, I see a lot of people asking about UNC paths. Simply mapping the unc path to a drive letter will make forfiles happy. Mapping and unmapping of drives can be done programmatically in a batch file, for example.</p>\n\n<pre><code>net use Z: /delete\nnet use Z: \\\\unc\\path\\to\\my\\folder\nforfiles /p Z: /s /m *.gz /D -7 /C "cmd /c del @path"\n</code></pre>\n\n<p>This will delete all files with a .gz extension that are older than 7 days. If you want to make sure Z: isn\'t mapped to anything else before using it you could do something simple as</p>\n\n<pre><code>net use Z: \\\\unc\\path\\to\\my\\folder\nif %errorlevel% equ 0 (\n    forfiles /p Z: /s /m *.gz /D -7 /C "cmd /c del @path"\n) else (\n    echo "Z: is already in use, please use another drive letter!"\n)\n</code></pre>\n'}, {'answer_id': 28395552, 'author': 'Mofi', 'author_id': 3074564, 'author_profile': 'https://Stackoverflow.com/users/3074564', 'pm_score': 3, 'selected': False, 'text': '<p>There are very often relative date/time related questions to solve with batch file. But command line interpreter <strong>cmd.exe</strong> has no function for date/time calculations. Lots of good working solutions using additional console applications or scripts have been posted already here, on other pages of Stack Overflow and on other websites.</p>\n<p>Common for operations based on date/time is the requirement to convert a date/time string to seconds since a determined day. Very common is 1970-01-01 00:00:00 UTC. But any later day could be also used depending on the date range required to support for a specific task.</p>\n<p><a href="https://stackoverflow.com/users/151152/jay">Jay</a> posted <a href="https://stackoverflow.com/a/1322886/3074564">7daysclean.cmd</a> containing a fast &quot;date to seconds&quot; solution for command line interpreter <strong>cmd.exe</strong>. But it does not take leap years correct into account. <a href="https://stackoverflow.com/users/381472/j-r">J.R.</a> posted an <a href="https://stackoverflow.com/a/3161104/3074564">add-on</a> for taking leap day in current year into account, but ignoring the other leap years since base year, i.e. since 1970.</p>\n<p>I use since 20 years static tables (arrays) created once with a small C function for quickly getting the number of days including leap days from 1970-01-01 in date/time conversion functions in my applications written in C/C++.</p>\n<p>This very fast table method can be used also in batch code using <strong>FOR</strong> command. So I decided to code the batch subroutine <code>GetSeconds</code> which calculates the number of seconds since 1970-01-01 00:00:00 UTC for a date/time string passed to this routine.</p>\n<p><strong>Note:</strong> Leap seconds are not taken into account as the Windows file systems also do not support leap seconds.</p>\n<p>First, the tables:</p>\n<ol>\n<li><p>Days since 1970-01-01 00:00:00 UTC for each year including leap days.</p>\n<pre><code>1970 - 1979:     0   365   730  1096  1461  1826  2191  2557  2922  3287\n1980 - 1989:  3652  4018  4383  4748  5113  5479  5844  6209  6574  6940\n1990 - 1999:  7305  7670  8035  8401  8766  9131  9496  9862 10227 10592\n2000 - 2009: 10957 11323 11688 12053 12418 12784 13149 13514 13879 14245\n2010 - 2019: 14610 14975 15340 15706 16071 16436 16801 17167 17532 17897\n2020 - 2029: 18262 18628 18993 19358 19723 20089 20454 20819 21184 21550\n2030 - 2039: 21915 22280 22645 23011 23376 23741 24106 24472 24837 25202\n2040 - 2049: 25567 25933 26298 26663 27028 27394 27759 28124 28489 28855\n2050 - 2059: 29220 29585 29950 30316 30681 31046 31411 31777 32142 32507\n2060 - 2069: 32872 33238 33603 33968 34333 34699 35064 35429 35794 36160\n2070 - 2079: 36525 36890 37255 37621 37986 38351 38716 39082 39447 39812\n2080 - 2089: 40177 40543 40908 41273 41638 42004 42369 42734 43099 43465\n2090 - 2099: 43830 44195 44560 44926 45291 45656 46021 46387 46752 47117\n2100 - 2106: 47482 47847 48212 48577 48942 49308 49673\n</code></pre>\n<p>Calculating the seconds for year 2039 to 2106 with epoch beginning 1970-01-01 is only possible with using an unsigned 32-bit variable, i.e. unsigned long (or unsigned int) in C/C++.</p>\n<p>But <strong>cmd.exe</strong> use for mathematical expressions a signed 32-bit variable. Therefore the maximum value is 2147483647 (0x7FFFFFFF) which is 2038-01-19 03:14:07.</p>\n</li>\n<li><p>Leap year information (No/Yes) for the years 1970 to 2106.</p>\n<pre><code>1970 - 1989: N N Y N N N Y N N N Y N N N Y N N N Y N\n1990 - 2009: N N Y N N N Y N N N Y N N N Y N N N Y N\n2010 - 2029: N N Y N N N Y N N N Y N N N Y N N N Y N\n2030 - 2049: N N Y N N N Y N N N Y N N N Y N N N Y N\n2050 - 2069: N N Y N N N Y N N N Y N N N Y N N N Y N\n2070 - 2089: N N Y N N N Y N N N Y N N N Y N N N Y N\n2090 - 2106: N N Y N N N Y N N N N N N N Y N N\n                                 ^ year 2100\n</code></pre>\n</li>\n<li><p>Number of days to first day of each month in current year.</p>\n<pre><code>                   Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec\nYear with 365 days:  0  31  59  90 120 151 181 212 243 273 304 334\nYear with 366 days:  0  31  60  91 121 152 182 213 244 274 305 335\n</code></pre>\n</li>\n</ol>\n<p>Converting a date to number of seconds since 1970-01-01 is quite easy using those tables.</p>\n<p><strong>Attention please!</strong></p>\n<p>The format of date and time strings depends on Windows region and language settings. The delimiters and the order of tokens assigned to the environment variables <code>Day</code>, <code>Month</code> and <code>Year</code> in first <strong>FOR</strong> loop of <code>GetSeconds</code> must be adapted to local date/time format if necessary.</p>\n<p>It is necessary to adapt the date string of the environment variable if date format in environment variable <strong>DATE</strong> is different to date format used by command <strong>FOR</strong> on <code>%%~tF</code>.</p>\n<p>For example when <code>%DATE%</code> expands to <code>Sun 02/08/2015</code> while <code>%%~tF</code> expands to <code>02/08/2015 07:38 PM</code> the code below can be used with modifying line 4 to:</p>\n<pre><code>call :GetSeconds &quot;%DATE:~4% %TIME%&quot;\n</code></pre>\n<p>This results in passing to subroutine just <code>02/08/2015</code> - the date string without the 3 letters of weekday abbreviation and the separating space character.</p>\n<p>Alternatively following could be used to pass current date in correct format:</p>\n<pre><code>call :GetSeconds &quot;%DATE:~-10% %TIME%&quot;\n</code></pre>\n<p>Now the last 10 characters from date string are passed to function <code>GetSeconds</code> and therefore it does not matter if date string of environment variable <strong>DATE</strong> is with or without weekday as long as day and month are always with 2 digits in expected order, i.e. in format <code>dd/mm/yyyy</code>  or <code>dd.mm.yyyy</code>.</p>\n<p>Here is the batch code with explaining comments which just outputs which file to delete and which file to keep in <code>C:\\Temp</code> folder tree, see code of first <strong>FOR</strong> loop.</p>\n<pre><code>@echo off\nsetlocal EnableExtensions DisableDelayedExpansion\nrem Get seconds since 1970-01-01 for current date and time.\ncall :GetSeconds &quot;%DATE% %TIME%&quot;\nrem Subtract seconds for 7 days from seconds value.\nset /A &quot;LastWeek=Seconds-7*86400&quot;\n\nrem For each file in each subdirectory of C:\\Temp get last modification date\nrem (without seconds -&gt; append second 0) and determine the number of seconds\nrem since 1970-01-01 for this date/time. The file can be deleted if seconds\nrem value is lower than the value calculated above.\n\nfor /F &quot;delims=&quot; %%# in (\'dir /A-D-H-S /B /S &quot;C:\\Temp&quot;\') do (\n    call :GetSeconds &quot;%%~t#:0&quot;\n    set &quot;FullFileName=%%#&quot;\n    setlocal EnableDelayedExpansion\n    rem if !Seconds! LSS %LastWeek% del /F &quot;!FullFileName!&quot;\n    if !Seconds! LEQ %LastWeek% (\n        echo Delete &quot;!FullFileName!&quot;\n    ) else (\n        echo Keep   &quot;!FullFileName!&quot;\n    )\n    endlocal\n)\nendlocal\ngoto :EOF\n\n\nrem No validation is made for best performance. So make sure that date\nrem and hour in string is in a format supported by the code below like\nrem MM/DD/YYYY hh:mm:ss or M/D/YYYY h:m:s for English US date/time.\n\n:GetSeconds\nrem If there is &quot; AM&quot; or &quot; PM&quot; in time string because of using 12 hour\nrem time format, remove those 2 strings and in case of &quot; PM&quot; remember\nrem that 12 hours must be added to the hour depending on hour value.\n\nset &quot;DateTime=%~1&quot;\nset &quot;Add12Hours=0&quot;\nif not &quot;%DateTime: AM=%&quot; == &quot;%DateTime%&quot; (\n    set &quot;DateTime=%DateTime: AM=%&quot;\n) else if not &quot;%DateTime: PM=%&quot; == &quot;%DateTime%&quot; (\n    set &quot;DateTime=%DateTime: PM=%&quot;\n    set &quot;Add12Hours=1&quot;\n)\n\nrem Get year, month, day, hour, minute and second from first parameter.\n\nfor /F &quot;tokens=1-6 delims=,-./: &quot; %%A in (&quot;%DateTime%&quot;) do (\n    rem For English US date MM/DD/YYYY or M/D/YYYY\n    set &quot;Day=%%B&quot; &amp; set &quot;Month=%%A&quot; &amp; set &quot;Year=%%C&quot;\n    rem For German date DD.MM.YYYY or English UK date DD/MM/YYYY\n    rem set &quot;Day=%%A&quot; &amp; set &quot;Month=%%B&quot; &amp; set &quot;Year=%%C&quot;\n    set &quot;Hour=%%D&quot; &amp; set &quot;Minute=%%E&quot; &amp; set &quot;Second=%%F&quot;\n)\nrem echo Date/time is: %Year%-%Month%-%Day% %Hour%:%Minute%:%Second%\n\nrem Remove leading zeros from the date/time values or calculation could be wrong.\nif &quot;%Month:~0,1%&quot;  == &quot;0&quot; if not &quot;%Month:~1%&quot;  == &quot;&quot; set &quot;Month=%Month:~1%&quot;\nif &quot;%Day:~0,1%&quot;    == &quot;0&quot; if not &quot;%Day:~1%&quot;    == &quot;&quot; set &quot;Day=%Day:~1%&quot;\nif &quot;%Hour:~0,1%&quot;   == &quot;0&quot; if not &quot;%Hour:~1%&quot;   == &quot;&quot; set &quot;Hour=%Hour:~1%&quot;\nif &quot;%Minute:~0,1%&quot; == &quot;0&quot; if not &quot;%Minute:~1%&quot; == &quot;&quot; set &quot;Minute=%Minute:~1%&quot;\nif &quot;%Second:~0,1%&quot; == &quot;0&quot; if not &quot;%Second:~1%&quot; == &quot;&quot; set &quot;Second=%Second:~1%&quot;\n\nrem Add 12 hours for time range 01:00:00 PM to 11:59:59 PM,\nrem but keep the hour as is for 12:00:00 PM to 12:59:59 PM.\nif %Add12Hours% == 1 if %Hour% LSS 12 set /A Hour+=12\n\nset &quot;DateTime=&quot;\nset &quot;Add12Hours=&quot;\n\nrem Must use two arrays as more than 31 tokens are not supported\nrem by command line interpreter cmd.exe respectively command FOR.\nset /A &quot;Index1=Year-1979&quot;\nset /A &quot;Index2=Index1-30&quot;\n\nif %Index1% LEQ 30 (\n    rem Get number of days to year for the years 1980 to 2009.\n    for /F &quot;tokens=%Index1% delims= &quot; %%Y in (&quot;3652 4018 4383 4748 5113 5479 5844 6209 6574 6940 7305 7670 8035 8401 8766 9131 9496 9862 10227 10592 10957 11323 11688 12053 12418 12784 13149 13514 13879 14245&quot;) do set &quot;Days=%%Y&quot;\n    for /F &quot;tokens=%Index1% delims= &quot; %%L in (&quot;Y N N N Y N N N Y N N N Y N N N Y N N N Y N N N Y N N N Y N&quot;) do set &quot;LeapYear=%%L&quot;\n) else (\n    rem Get number of days to year for the years 2010 to 2038.\n    for /F &quot;tokens=%Index2% delims= &quot; %%Y in (&quot;14610 14975 15340 15706 16071 16436 16801 17167 17532 17897 18262 18628 18993 19358 19723 20089 20454 20819 21184 21550 21915 22280 22645 23011 23376 23741 24106 24472 24837&quot;) do set &quot;Days=%%Y&quot;\n    for /F &quot;tokens=%Index2% delims= &quot; %%L in (&quot;N N Y N N N Y N N N Y N N N Y N N N Y N N N Y N N N Y N N&quot;) do set &quot;LeapYear=%%L&quot;\n)\n\nrem Add the days to month in year.\nif &quot;%LeapYear%&quot; == &quot;N&quot; (\n    for /F &quot;tokens=%Month% delims= &quot; %%M in (&quot;0 31 59 90 120 151 181 212 243 273 304 334&quot;) do set /A &quot;Days+=%%M&quot;\n) else (\n    for /F &quot;tokens=%Month% delims= &quot; %%M in (&quot;0 31 60 91 121 152 182 213 244 274 305 335&quot;) do set /A &quot;Days+=%%M&quot;\n)\n\nrem Add the complete days in month of year.\nset /A &quot;Days+=Day-1&quot;\n\nrem Calculate the seconds which is easy now.\nset /A &quot;Seconds=Days*86400+Hour*3600+Minute*60+Second&quot;\n\nrem Exit this subroutine.\ngoto :EOF\n</code></pre>\n<p>For optimal performance it would be best to remove all comments, i.e. all lines starting with <strong>rem</strong> after 0-4 leading spaces.</p>\n<p>And the arrays can be made also smaller, i.e. decreasing the time range from 1980-01-01 00:00:00 to 2038-01-19 03:14:07 as currently supported by the batch code above for example to 2015-01-01 to 2019-12-31 as the code below uses which really deletes files older than 7 days in <code>C:\\Temp</code> folder tree.</p>\n<p>Further the batch code below is optimized for 24 hours time format.</p>\n<pre><code>@echo off\nsetlocal EnableExtensions DisableDelayedExpansion\ncall :GetSeconds &quot;%DATE:~-10% %TIME%&quot;\nset /A &quot;LastWeek=Seconds-7*86400&quot;\n\nfor /F &quot;delims=&quot; %%# in (\'dir /A-D-H-S /B /S &quot;C:\\Temp&quot;\') do (\n    call :GetSeconds &quot;%%~t#:0&quot;\n    set &quot;FullFileName=%%#&quot;\n    setlocal EnableDelayedExpansion\n    if !Seconds! LSS %LastWeek% del /F &quot;!FullFileName!&quot;\n    endlocal\n)\nendlocal\ngoto :EOF\n\n:GetSeconds\nfor /F &quot;tokens=1-6 delims=,-./: &quot; %%A in (&quot;%~1&quot;) do (\n    set &quot;Day=%%B&quot; &amp; set &quot;Month=%%A&quot; &amp; set &quot;Year=%%C&quot;\n    set &quot;Hour=%%D&quot; &amp; set &quot;Minute=%%E&quot; &amp; set &quot;Second=%%F&quot;\n)\nif &quot;%Month:~0,1%&quot;  == &quot;0&quot; if not &quot;%Month:~1%&quot;  == &quot;&quot; set &quot;Month=%Month:~1%&quot;\nif &quot;%Day:~0,1%&quot;    == &quot;0&quot; if not &quot;%Day:~1%&quot;    == &quot;&quot; set &quot;Day=%Day:~1%&quot;\nif &quot;%Hour:~0,1%&quot;   == &quot;0&quot; if not &quot;%Hour:~1%&quot;   == &quot;&quot; set &quot;Hour=%Hour:~1%&quot;\nif &quot;%Minute:~0,1%&quot; == &quot;0&quot; if not &quot;%Minute:~1%&quot; == &quot;&quot; set &quot;Minute=%Minute:~1%&quot;\nif &quot;%Second:~0,1%&quot; == &quot;0&quot; if not &quot;%Second:~1%&quot; == &quot;&quot; set &quot;Second=%Second:~1%&quot;\nset /A &quot;Index=Year-2014&quot;\nfor /F &quot;tokens=%Index% delims= &quot; %%Y in (&quot;16436 16801 17167 17532 17897&quot;) do set &quot;Days=%%Y&quot;\nfor /F &quot;tokens=%Index% delims= &quot; %%L in (&quot;N Y N N N&quot;) do set &quot;LeapYear=%%L&quot;\nif &quot;%LeapYear%&quot; == &quot;N&quot; (\n    for /F &quot;tokens=%Month% delims= &quot; %%M in (&quot;0 31 59 90 120 151 181 212 243 273 304 334&quot;) do set /A &quot;Days+=%%M&quot;\n) else (\n    for /F &quot;tokens=%Month% delims= &quot; %%M in (&quot;0 31 60 91 121 152 182 213 244 274 305 335&quot;) do set /A &quot;Days+=%%M&quot;\n)\nset /A &quot;Days+=Day-1&quot;\nset /A &quot;Seconds=Days*86400+Hour*3600+Minute*60+Second&quot;\ngoto :EOF\n</code></pre>\n<p>For even more information about date and time formats and file time comparisons on Windows see my answer on <a href="https://stackoverflow.com/a/32670346/3074564">Find out if file is older than 4 hours in batch file</a> with lots of additional information about file times.</p>\n'}, {'answer_id': 29420453, 'author': 'Sting', 'author_id': 782991, 'author_profile': 'https://Stackoverflow.com/users/782991', 'pm_score': 3, 'selected': False, 'text': '<p>Might I add a humble contribution to this already valuable thread.  I\'m finding that other solutions might get rid of the actual error text but are ignoring the %ERRORLEVEL% which signals a fail in my application. AND I legitimately want %ERRORLEVEL% just as long as it isn\'t the "No files found" error.</p>\n\n<p><strong>Some Examples:</strong></p>\n\n<p><strong>Debugging and eliminating the error specifically:</strong> </p>\n\n<pre><code>forfiles /p "[file path...]\\IDOC_ARCHIVE" /s /m *.txt /d -1 /c "cmd /c del @path" 2&gt;&amp;1 |  findstr /V /O /C:"ERROR: No files found with the specified search criteria."2&gt;&amp;1 | findstr ERROR&amp;&amp;ECHO found error||echo found success\n</code></pre>\n\n<p><strong>Using a oneliner to return ERRORLEVEL success or failure:</strong></p>\n\n<pre><code>forfiles /p "[file path...]\\IDOC_ARCHIVE" /s /m *.txt /d -1 /c "cmd /c del @path" 2&gt;&amp;1 |  findstr /V /O /C:"ERROR: No files found with the specified search criteria."2&gt;&amp;1 | findstr ERROR&amp;&amp;EXIT /B 1||EXIT /B 0\n</code></pre>\n\n<p><strong>Using a oneliner to keep the ERRORLEVEL at zero for success within the context of a batchfile in the midst of other code (ver > nul resets the ERRORLEVEL):</strong></p>\n\n<pre><code>forfiles /p "[file path...]\\IDOC_ARCHIVE" /s /m *.txt /d -1 /c "cmd /c del @path" 2&gt;&amp;1 |  findstr /V /O /C:"ERROR: No files found with the specified search criteria."2&gt;&amp;1 | findstr ERROR&amp;&amp;ECHO found error||ver &gt; nul\n</code></pre>\n\n<p><strong>For a SQL Server Agent CmdExec job step I landed on the following. I don\'t know if it\'s a bug, but the CmdExec within the step only recognizes the first line of code:</strong></p>\n\n<pre><code>cmd /e:on /c "forfiles /p "C:\\SQLADMIN\\MAINTREPORTS\\SQL2" /s /m *.txt /d -1 /c "cmd /c del @path" 2&gt;&amp;1 |  findstr /V /O /C:"ERROR: No files found with the specified search criteria."2&gt;&amp;1 | findstr ERROR&amp;&amp;EXIT 1||EXIT 0"&amp;exit %errorlevel%\n</code></pre>\n'}, {'answer_id': 31628166, 'author': 'Viktor Ka', 'author_id': 4329986, 'author_profile': 'https://Stackoverflow.com/users/4329986', 'pm_score': 4, 'selected': False, 'text': '<p>For windows 2012 R2 the following  would work:</p>\n\n<pre><code>    forfiles /p "c:\\FOLDERpath" /d -30 /c "cmd /c del @path"\n</code></pre>\n\n<p>to see the files which will be deleted use this</p>\n\n<pre><code>    forfiles /p "c:\\FOLDERpath" /d -30 /c "cmd /c echo @path @fdate"\n</code></pre>\n'}, {'answer_id': 38958120, 'author': 'Shawn Pauliszyn', 'author_id': 5095809, 'author_profile': 'https://Stackoverflow.com/users/5095809', 'pm_score': 2, 'selected': False, 'text': '<p><strong>ROBOCOPY</strong> works great for me.  Originally suggested my Iman.  But instead of moving the files/folders to a temporary directory then deleting the contents of the temporary folder, <strong>move the files to the trash!!!</strong>  </p>\n\n<p>This is is a few lines of my backup batch file for example:</p>\n\n<pre><code>SET FilesToClean1=C:\\Users\\pauls12\\Temp\nSET FilesToClean2=C:\\Users\\pauls12\\Desktop\\1616 - Champlain\\Engineering\\CAD\\Backups\n\nSET RecycleBin=C:\\$Recycle.Bin\\S-1-5-21-1480896384-1411656790-2242726676-748474\n\nrobocopy "%FilesToClean1%" "%RecycleBin%" /mov /MINLAD:15 /XA:SH /NC /NDL /NJH /NS /NP /NJS\nrobocopy "%FilesToClean2%" "%RecycleBin%" /mov /MINLAD:30 /XA:SH /NC /NDL /NJH /NS /NP /NJS\n</code></pre>\n\n<p>It cleans anything older than 15 days out of my \'Temp\' folder and 30 days for anything in my AutoCAD backup folder.  I use variables because the line can get quite long and I can reuse them for other locations.  You just need to find the dos path to your recycle bin associated with your login.</p>\n\n<p>This is on a work computer for me and it works.  I understand that some of you may have more restrictive rights but give it a try anyway;)  Search Google for explanations on the ROBOCOPY parameters.</p>\n\n<p>Cheers!</p>\n'}, {'answer_id': 44065466, 'author': 'Snickbrack', 'author_id': 3992990, 'author_profile': 'https://Stackoverflow.com/users/3992990', 'pm_score': 1, 'selected': False, 'text': '<p>This one did it for me. It works with a date and you can substract the wanted amount in years to go back in time:</p>\n\n<pre><code>@echo off\n\nset m=%date:~-7,2%\nset /A m\nset dateYear=%date:~-4,4%\nset /A dateYear -= 2\nset DATE_DIR=%date:~-10,2%.%m%.%dateYear% \n\nforfiles /p "C:\\your\\path\\here\\" /s /m *.* /d -%DATE_DIR% /c "cmd /c del @path /F"\n\npause\n</code></pre>\n\n<p>the <code>/F</code> in the <code>cmd /c del @path /F</code> forces the specific file to be deleted in some the cases the file can be read-only.</p>\n\n<p>the <code>dateYear</code> is the year Variable and there you can change the substract to your own needs</p>\n'}, {'answer_id': 45113009, 'author': 'efdummy', 'author_id': 2513412, 'author_profile': 'https://Stackoverflow.com/users/2513412', 'pm_score': 1, 'selected': False, 'text': '<p>My script to delete files older than a specific year :</p>\n\n<pre><code>@REM _______ GENERATE A CMD TO DELETE FILES OLDER THAN A GIVEN YEAR\n@REM _______ (given in _olderthanyear variable)\n@REM _______ (you must LOCALIZE the script depending on the dir cmd console output)\n@REM _______ (we assume here the following line\'s format "11/06/2017  15:04            58\xa0389 SpeechToText.zip")\n\n@set _targetdir=c:\\temp\n@set _olderthanyear=2017\n\n@set _outfile1="%temp%\\deleteoldfiles.1.tmp.txt"\n@set _outfile2="%temp%\\deleteoldfiles.2.tmp.txt"\n\n  @if not exist "%_targetdir%" (call :process_error 1 DIR_NOT_FOUND "%_targetdir%") &amp; (goto :end)\n\n:main\n  @dir /a-d-h-s /s /b %_targetdir%\\*&gt;%_outfile1%\n  @for /F "tokens=*" %%F in (\'type %_outfile1%\') do @call :process_file_path "%%F" %_outfile2%\n  @goto :end\n\n:end\n  @rem ___ cleanup and exit\n  @if exist %_outfile1% del %_outfile1%\n  @if exist %_outfile2% del %_outfile2%\n  @goto :eof\n\n:process_file_path %1 %2\n  @rem ___ get date info of the %1 file path\n  @dir %1 | find "/" | find ":" &gt; %2\n  @for /F "tokens=*" %%L in (\'type %2\') do @call :process_line "%%L" %1\n  @goto :eof\n\n:process_line %1 %2\n  @rem ___ generate a del command for each file older than %_olderthanyear%\n  @set _var=%1\n  @rem  LOCALIZE HERE (char-offset,string-length)\n  @set _fileyear=%_var:~0,4%\n  @set _fileyear=%_var:~7,4%\n  @set _filepath=%2\n  @if %_fileyear% LSS %_olderthanyear% echo @REM %_fileyear%\n  @if %_fileyear% LSS %_olderthanyear% echo @del %_filepath%\n  @goto :eof\n\n:process_error %1 %2\n  @echo RC=%1 MSG=%2 %3\n  @goto :eof\n</code></pre>\n'}, {'answer_id': 49322063, 'author': 'GBGOLC', 'author_id': 2048573, 'author_profile': 'https://Stackoverflow.com/users/2048573', 'pm_score': 3, 'selected': False, 'text': "<p>Gosh, a lot of answers already. A simple and convenient route I found was to execute ROBOCOPY.EXE twice in sequential order from a single Windows command line instruction using the <strong>&amp;</strong> parameter.</p>\n\n<pre><code>ROBOCOPY.EXE SOURCE-DIR TARGET-DIR *.* /MOV /MINAGE:30 &amp; ROBOCOPY.EXE SOURCE-DIR TARGET-DIR *.* /MOV /MINAGE:30 /PURGE\n</code></pre>\n\n<p>In this example it works by picking all files (<em>.</em>) that are older than 30 days old and moving them to the target folder. The second command does the same again with the addition of the <strong>PURGE</strong> command which means remove files in the target folder that don’t exist in the source folder.\nSo essentially, the first command MOVES files and the second DELETES because they no longer exist in the source folder when the second command is invoked.</p>\n\n<p>Consult ROBOCOPY's documentation and use the /L switch when testing.</p>\n"}, {'answer_id': 64800901, 'author': 'npocmaka', 'author_id': 388389, 'author_profile': 'https://Stackoverflow.com/users/388389', 'pm_score': 0, 'selected': False, 'text': '<p>More flexible way is to use <a href="https://github.com/npocmaka/batch.scripts/blob/master/hybrids/jscript/FileTimeFilterJS.bat" rel="nofollow noreferrer"><code>FileTimeFilterJS.bat</code></a>:</p>\n<pre><code>@echo off\n\n::::::::::::::::::::::\nset &quot;_DIR=C:\\Users\\npocmaka\\Downloads&quot;\nset &quot;_DAYS=-5&quot;\n::::::::::::::::::::::\n\nfor /f &quot;tokens=* delims=&quot; %%# in (\'FileTimeFilterJS.bat  &quot;%_DIR%&quot; -dd %_DAYS%\') do (\n    echo deleting  &quot;%%~f#&quot;\n    echo del /q /f &quot;%%~f#&quot;\n)\n</code></pre>\n<p>The script will allow you to use measurements like days, minutes ,seconds or hours.\nTo choose weather to filter the files by time of creation, access or modification\nTo list files before or after a certain date (or between two dates)\nTo choose if to show files or dirs (or both)\nTo be recursive or not</p>\n'}, {'answer_id': 66343607, 'author': 'Miguel Carrillo', 'author_id': 11762632, 'author_profile': 'https://Stackoverflow.com/users/11762632', 'pm_score': 3, 'selected': False, 'text': '<p><strong>Delete all Files older than 3 days</strong></p>\n<pre><code>forfiles -p &quot;C:\\folder&quot; -m *.* -d -3 -c &quot;cmd  /c del /q @path&quot;\n</code></pre>\n<p><strong>Delete Directories older than 3 days</strong></p>\n<pre><code>forfiles -p &quot;C:\\folder&quot; -d -3 -c &quot;cmd  /c IF @isdir == TRUE rd /S /Q @path&quot;\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/51054', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/1862/']