Batch file to delete files older than N days
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.
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 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.
forfiles -p "C:\what\ever" -s -m *.* -d <number of days> -c "cmd /c del @path"
forfiles documentation for more details.
For more goodies, refer to An A-Z Index of the Windows XP command line.
If you don't have
forfiles installed on your machine, copy it from any Windows Server 2003 to your Windows XP machine at
%WinDir%\system32\. This is possible since the EXE is fully compatible between Windows Server 2003 and Windows XP.
Later versions of Windows and Windows Server have it installed by default.
For Windows 7 and newer (including Windows 10):
The syntax has changed a little. Therefore the updated command is:
forfiles /p "C:\what\ever" /s /m *.* /D -<number of days> /C "cmd /c del @path"
Read more... Read less...
Run the following commands:
ROBOCOPY C:\source C:\destination /mov /minage:7 del C:\destination /q
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.
Also if you have a directory with lots of data in it you can use
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):
@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: 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 : Change 7 for the number of days to keep.
set dSource=C:\temp : This is the starting directory to check for files.
This is non-destructive code, it will display what would have happened.
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. 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.
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.
epoch 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).
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.
forfiles /p "v:" /s /m *.* /d -3 /c "cmd /c del @path"
You should do
/d -3 (3 days earlier) This works fine for me. So all the complicated batches could be in the trash bin. Also
forfiles don't support UNC paths, so make a network connection to a specific drive.
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.
My command is
forfiles -p "d:\logs" -s -m*.log -d-15 -c"cmd /c del @PATH\@FILE"
@PATH - is just path in my case, so I had to use
forfiles /? not working for me too, but
forfiles (without "?") worked fine.
And the only question I have: how to add multiple mask (for example ".log|.bak")?
All this regarding forfiles.exe that I downloaded here (on win XP)
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.
For Windows Server 2003 I'm using this command:
forfiles -p "d:\Backup" -s -m *.log -d -15 -c "cmd /c del @PATH"