views:

43951

answers:

12

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.

+27  A: 

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

aku
I don't have forfiles on my XP (sp3) machine - where'd that come from?
Blorgbeard
You should have onehttp://webtools.live2support.com/windows/forfiles.php
aku
Should be del @FILE, case mattersAlso I suggest using /c echo @FILE for testing
Russell Steen
I have been using SS64.com for years. That site is a good reference.
JustSmith
@Russell: @PATH is the full path, including name. @FILE is only the name, so if you're dealing with subfolders, it won't work.
gregmac
Note that if you want files OLDER than 10 days, you need to specify -d "-10". -ve means "older than", +ve means "newer than". You can also specify DDMMYY or -DDMMYY format as the parameter to -d.
gregmac
When I tested it under Windows 7, @PATH was just the path, and @FILE was just the file name. I used @PATH\@FILE for the del command.
Chris
Well you learn something new every day... never come across forfiles before :-)
Chris J
+1  A: 

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.

Kibbee
interesting, I have in on my WinXP SP3 and Win2k server by default
aku
A: 

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.

bryan314
What's with the advertisement-laden link?
Kibbee
+1  A: 

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.

Paulius Maruška
+1  A: 

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.

Jay
+1  A: 

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.

e.James
+1  A: 

doesn't work at all...

+1  A: 

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...

Murph
+1  A: 

Awsome, it works !!!

Thanks Madjid

Madjid
A: 

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 ...

J.R.
A: 

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

aastha