7

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?

ErocM
  • 4,151
  • 22
  • 84
  • 152

2 Answers2

11

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

David Ruhmann
  • 10,344
  • 2
  • 32
  • 46
  • I ran your command on my 99 `.txt` files (`for /f "skip=30 delims=" %i in ('dir /a-d /b /o-d /tc *.txt ^2^>nul') do del %i`), and it deleted 1-39 and 70-99, leaving 40.txt - 69.txt. The next two times I tried it, it worked just fine. Very odd! – James L. Jan 10 '13 at 21:10
  • Important to note that, if you want to run this command directly on terminal (outside a batch file), you must replace all "%%" to "%". – Diego Queiroz Sep 30 '16 at 17:54
4

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
James L.
  • 8,959
  • 3
  • 34
  • 74
  • 1
    how do I incorporate the %BKUPDIR% in with the del? I'm having issues getting that to work correctly. – ErocM Jan 10 '13 at 21:15
  • your example was great, I just happened on his answer first. They both worked so I gave you a +1. Thank you for the help! This gives me a few ideas for changes with what I currently have. – ErocM Jan 10 '13 at 21:26