I'm writing a simple .bat backup script, and as part of it I want the oldest backup (folder) to be deleted upon reaching a set max limit of backups.
Right now I have this:
%COUNTER%
is based on the number of backup folders currently in the directory where backups are stored, and is calculated earlier in the script.
%MAXBACKUPS%
is just a user-specified number like "10," to say that you only want to keep up to 10 versions of the backups.
:: Delete the oldest backup, but only if we've exceeded the desired number of backups.
IF %COUNTER% gtr %MAXBACKUPS% (
ECHO More than %MAXBACKUPS% backups exist. Deleting oldest...
FOR /f "delims=" %%a in ('dir "..\Backup\*" /t:c /a:d /o:-d /b') do rd /s /q "..\Backup\%%a"
::Increment the counter down since we've just removed a backup folder.
SET /a COUNTER=%COUNTER%-1
)
I would like this script to only delete the one oldest folder in the ..\Backup
folder, but as it stands it seems to delete every single folder it finds once it reaches the backup limit, which is obviously not the desired behavior.
You were so close ! :-)
All you need to do is skip the first %MAXBACKUPS%
entries when sorted by date descending. You don't even need your COUNTER
variable.
:: Preserve only the %MAXBACKUPS% most recent backups.
set "delMsg="
for /f "skip=%MAXBACKUPS% delims=" %%a in (
'dir "..\Backup\*" /t:c /a:d /o:-d /b'
) do (
if not defined delMsg (
set delMsg=1
echo More than %MAXBACKUPS% found - only the %MAXBACKUPS% most recent folders will be preserved.
)
rd /s /q "..\Backup\%%a"
)
A simple way to do this based on your script:
FOR /f "delims=" %%a in ('dir "..\Backup\*" /t:c /a:d /o:-d /b') do set lastfolder=%%a
rd /s /q "..\Backup\%lastfolder%"
So you still loop over each folder, sorted by age, but you overwrite %lastfolder% so at the end it contains only the name of the oldest folder.
Then you delete that folder.
Here's the final block of code I ended up using:
:: Preserve only the %MAXBACKUPS% most recent backups.
FOR /f "skip=%MAXBACKUPS% delims=" %%a in (
'dir "..\Backup\*" /t:c /a:d /o:-d /b'
) do (
ECHO More than %MAXBACKUPS% backups found--Deleting "%%a".
ECHO.
rd /s /q "..\Backup\%%a"
)
It simplifies the deletion message code a bit, and provides the end user with info about what file was deleted in the command prompt window.
Based on dbenham's answer.
FOR /f "delims=" %%a in ('dir "..\Backup\*" /t:c /a:d /o:d /b') do (
rd /s /q "..\Backup\%%a"
goto :break
)
:break
you can break the for loop with goto