Wednesday, 9 April 2014

Batch / Script to Remove Aged Files

Removing aged backup or log files from the windows command line - or by script
don't forget if running commands from the command line, the %% syntax becomes a single % (e.g. in the for command) and any environment variables set in the script (e.g. %bkpfolder%) need to be manually set within the command environment where the commands are being manually executed.

Purely date based removal

If you just want to remove files based solely on date, using the forfiles command is and easy awy to go.
The drawback with this is that if there haven't been any backup/log files created  within the aging-period, you can be left with NO files

Refer to MSDN for syntax or type forfiles /? at a windows command prompt

Using forfiles without the /C switch defaults to listing all files matching the /P (path) and /M (mask) criteria using its default /C string of "cmd /c echo @file" - thus:
forfiles /P h:\P6Backup /M *.bak
"20140404-PMDB - Copy.bak"

Add a /R (reverse) sort if you want the latest at the top of the list....
forfiles /P h:\P6Backup /M *.bak  | sort /R
"20140404-PMDB - Copy.bak"

using an alternate command string you can use forfiles with the last modified date
forfiles /P h:\P6Backup /M *.bak /C "cmd /c echo @fdate"

combine the /C command line functions to get the info you want
forfiles /P h:\P6Backup /M *.bak /C "cmd /c echo @fdate @file" | sort /R
7/04/2014 "20140407-PMDB.bak"
4/04/2014 "20140404-PMDB.bak"
4/04/2014 "20140404-PMDB - Copy.bak"

Now add the /D switch to only show the files older than -n days from the current date
forfiles /P h:\P6Backup /M *.bak /D -3 /C "cmd /c echo @fdate @file" | sort /R
4/04/2014 "20140404-PMDB.bak"
4/04/2014 "20140404-PMDB - Copy.bak"

Using a slightly altered /C command string to delete rather than display the older files results in the required date-managed elimination of older files
forfiles /P h:\P6Backup /M *.bak /D -3 /C "cmd /c del @fdate"

Retain at-least some files, removing the rest based on their date

To eliminate files based on date but keeping a minimum of n instances regardless of their date, can be achieved using the file looping /f switch of the for command along with the skip parameter

set  %bkpfolder%=P6Backup

REM Del all but the last 3 backups and last 10 logs
  for /f "skip=3 delims=" %%A in ('dir H:\%bkpfolder%\*.bak /a:-d /b /o:-d /t:w ^2^>nul') do if exist "H:\%bkpfolder%\%%A" del "H:\%bkpfolder%\%%A"
  for /f "skip=10 delims=" %%A in ('dir H:\%bkpfolder%\*.log /a:-d /b /o:-d /t:w ^2^>nul') do if exist "H:\%bkpfolder%\%%A" del "H:\%bkpfolder%\%%A"

Refer to Technet or type for /? at the command prompt for the correct for syntax
Refer to Technet or type dir /? at the command prompt for explanation of the switches used in the DIR command within the for loop where we use the atttribute (/a:) switch with it's -d parameter to exclude directories and the sortorder (/o:) switch with it's -d parameter to get the most recent-dated files first. We also use the timefield (/t:) switch with it's w parameter to sort using last-written times and use standard redirection of stderr (standard error) with 2>nul by employing escaped (^) syntax so that the 2>nul redirection of any errors to nul, becomes ^2^>nul

No comments: