Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Windows batch file only keeping the last 30 files

I have written a batch file that does the following:

REM @ECHO OFF
rem %1 = coid
rem %2 = rpg location with ending /

rem get the path of this cmd script
SET SUBDIR=%~dp0

SET BKUPDIR=%SUBDIR%BACKUPS\
SET LOGFILE=%BKUPDIR%backup.log

ECHO ************************************************* >>%LOGFILE%
ECHO STARTING BACKUP FOR %1 AT %2 >>%LOGFILE%

FOR /f "skip=1" %%x in ('wmic os get localdatetime') DO IF NOT defined mydate SET mydate=%%x
SET filedate=%mydate:~0,14%
SET fullname=%BKUPDIR%%1_%FILEDATE%.ZIP

ECHO BKUPDIR: %BKUPDIR% >>%LOGFILE%
ECHO mydate: %mydate% >>%LOGFILE%
ECHO filedate: %filedate% >>%LOGFILE%
ECHO fullname: %fullname% >>%LOGFILE%
ECHO SUBDIR: %SUBDIR% >>%LOGFILE%

rem lets make sure the backup directory exists before starting
IF NOT EXIST %BKUPDIR% MD %BKUPDIR% >>%LOGFILE%

%SUBDIR%7z a -tzip %fullname%  %2%1*.d
IF ERRORLEVEL 255 ECHO user_stopped_the_process >>%LOGFILE%
IF ERRORLEVEL 8 ECHO not_enough_memory >>%LOGFILE%
IF ERRORLEVEL 7 ECHO command_line_error >>%LOGFILE%
IF ERRORLEVEL 2 ECHO fatal_error >>%LOGFILE%
IF ERRORLEVEL 1 ECHO ok_warnings >>%LOGFILE%

IF ERRORLEVEL 0 GOTO END
IF EXIST %fullname% DEL %fullname%

:END
ECHO FINISHING BACKUP FOR %1 >>%LOGFILE%
ECHO ************************************************* >>%LOGFILE%
set mydate=

I am saving the files as the %1 and the date/time the file was created:

SSS_20130110133304.ZIP 
SSS_20130110133336.ZIP

I am running this in the task scheduler to run every night.

I want to keep from having too many zip files in the directory so I'd like to keep the last 30 zip files that exist.

I'm stuck at this point. How do I keep the most RECENT 30 zip files so that I don't end up with a crap load of zip files?

like image 895
ErocM Avatar asked Jan 10 '13 19:01

ErocM


2 Answers

This will list the .zip files from newest to oldest (by creation date), skipping the first 30 files.

for /f "skip=30 delims=" %%A in ('dir /a:-d /b /o:-d /t:c *.zip ^2^>nul') do if exist "%%~fA" echo "%%~fA"

Just change the echo to del when you want to actually delete the files. :)

like image 55
David Ruhmann Avatar answered Dec 03 '22 18:12

David Ruhmann


Just focusing on the question -- how to keep the 30 most recent files, and delete the rest:

You can do a dir > clean.lst with the proper sort, so that the most recent files are at the beginning of the clean.lst. Then you can use the for command to skip the first 30 lines in the file and delete the files that are listed after the 30th file.

Consider this test case:

C:>md xyz
C:>cd xyz
c:\xyz>copy con genfiles.bat
@echo off
set _i=1
:loop
if %_i%==100 goto :EOF
echo.>%_i%.txt
set /a _i+=1
goto loop
^Z
        1 file(s) copied.

c:\xyz>genfiles
c:\xyz>del genfiles.bat

Now you have 99 text files in the XYZ folder.

You can remove all but the 30 most recent like this:

C:\xyz>dir /b /o-d *.txt > clean.lst
C:\xyz>for /f "skip=30 delims=" %i in (clean.lst) do del "%i"
C:\xyz>del clean.lst

A dir shows only the text files 70.txt - 99.txt remain, the rest have been removed.

For your batch file, I think it would look something like this:

cd /d %BKUPDIR%
dir /b /o-d *.zip > clean.lst
for /f "skip=30 delims=" %%i in (clean.lst) do del "%%i"
del clean.lst
like image 34
James L. Avatar answered Dec 03 '22 18:12

James L.