I am looking for a way to delete all files older than 7 days in an MS-DOS batch file. I've search 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. Similar things can be done in BASH in just a couple lines of code. It seems that something at least remotely easy could be done for batch files 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.
Enjoy:
forfiles -p "C:\what\ever" -s -m *.* -d <number of days> -c "cmd /c del @path"
See forfiles /? for details
For more goodies see An A-Z Index of the Windows XP command line
If you don't have forfiles installed by default on your machine, get it from Microsoft FTP server. Place it to C:\WINDOWS\system32\forfiles.exe
forfiles is actually an extra thing you have to install. Although that seems like it's included in most of the best solutions i've seen around the internet. So I may just have to install it.
You're probably not going to find a totally non install solution short of a complicated bat file or windows script. I use delen, drop it in a system directory then use it like the regular del command in any bat file.
You might be able to pull this off. You can take a look at this question, 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.
In other words - don't try to invent this, unless you really can't use the third party tools.
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):
7daysclean.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 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
____Usage____
set /a strip=day*7: Change 7 for the number of days to keep.
set dSource=C:\temp: This is the starting directory to check for files.
____Notes____
This is non-destructive code, it will display what would have happened. Change :
if !epoch! LEQ %slice% (echo DELETE %%f ^(%%~tf^)) ELSE echo keep %%f ^(%%~tf^)
to something like :
if !epoch! LEQ %slice% del /f %%f
so files actually get deleted
february: is hard-coded to 28 days. Bisextile 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.
epoch: 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.
Did I mention I hate this editor's auto-formating? it removes the blank lines and the copy-paste is a hell.
I hope this helps.
Have a look at my answer to a similar question:
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"
This deletes files older than a given date. I'm sure it can be modified to go back seven days from the current date.
update: I notice that HerbCSO has improved on the above script. I recommend using his version instead.
one modification to the accepted answer I noticed: this doesn't seem to work if you put the number of days in any kind of parenthesis.
For mine, after the -d, I have "-4" so everything older then 4 days gets deleted.
Also, if you drop the actual batch file into the folder you wish to modify, you can skip the -p "C:\what\ever" piece
Just be careful to not delete the actual batch file. For mine, I have it only deleting older .bak files (not just *. *)
So, my whole line is: forfiles -s -m *.bak -d -4 -c "cmd /c del @path"
Thanks to AKU...
How about these modifications on 7daysclean.cmd to take a leap year in account. It can be done in less than 10 lines of coding!
... 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 ...
HI,
I am running the below batch file
@echo off setlocal ENABLEDELAYEDEXPANSION set day=86400 set /a year=day*365 set /a strip=day*2 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% del /f %%f ) 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 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
But the files are not being deleted. Could you please help.
//Aastha