Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!

RemoveAfter

May
401
4
Hello all. I needed a utility to keep a set of backup files to a certain number of days before today. For example, delete all *.backup files older than 90 days.

I created this simple library function, RemoveAfter, to take the number of days to keep and a file pattern.

Please note this does use 2 of my other library functions. Name links to function in this forum:
  • DebugPrint: Simply prints text in RED if the env variable DEBUG is set
  • GetOpt: Process command line options

I hope someone finds this useful. If you find a bug or have an improvement idea please let me know.

Michael

Code:
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: RemoveAfter[Days, Pattern]
::
:: Remove all files of the given pattern older than the Days provided.
::
:: Note, today's date is considered 1 day, so if you put a 1 as the 'Num Days', it
:: will remove all files older than today's date.
::
:: Also, only the "day" is considered, not the minutes or seconds.
::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
RemoveAfter {
    SetLocal

    :: Process parameters
    GetOpt %*

    :: If help is requested, show usage and exit
    if defined OPTION_h gosub Usage

    :: Enable debug mode if -d is provided
    if defined OPTION_d set Debug=1

    :: If test data creation is selected, generate it then exit
    if defined OPTION_t gosub GenerateTestData

    :: Display input debug information
    DebugPrint "Number of Parameters:  %PARAM_0"
    DebugPrint "Parameter 1:           %PARAM_1"
    DebugPrint "Parameter 2:           %PARAM_2"
    DebugPrint "NoPrompt:              %OPTION_n"
    DebugPrint "SimulationMode:        %OPTION_s"
    DebugPrint "Debug Mode:            %Option_d"

    :: Ensure 2 parameters were entered
    iff %PARAM_0 != 2 then
        echo ERROR: Two parameters are required^n
        gosub Usage
    endiff

    :: Ensure the first param is > 0
    iff %PARAM_1 lt 1 then
        echo ERROR: The NumDays parameter must be greater than zero^n
        gosub Usage
    endiff

    :: Ensure the file pattern matches something
    iff not exist %PARAM_2 then
        echo ERROR: The file pattern provided '%PARAM_2' in directory '%@Path[%PARAM_2]' does not exist^n
        gosub Usage
    endiff

    :: Determine if we want to disable prompts
    if defined OPTION_n set NoPrompt=1

    :: Detemrine if we are in Simulation Mode (this acts normaly but does not perform the delete)
    if defined OPTION_s set SimulationMode=1

    :: Determine end end date.  This is one less than the number provided by the user. This
    :: is so we include today's date as 1 instead of 0
    set EndDate=%@MakeDate[%@Eval[%@Date[%_Date]-%@Dec[%PARAM_1]],4]
    DebugPrint "Start Date: %_ISODate"
    DebugPrint "End Date:   %EndDate"

    echo RemoveAfter
    echo  - Current Working Directory is '%_CWD'
    echo  - Deleting everything older than %EndDate (%PARAM_1 days) matching the pattern '%PARAM_2'

    :: Loop through each file matching the pattern and older than the provided days
    echo  - Files To Delete %@if[defined SimulationMode,(Simulated)]:
    do Name in /![d%_ISODate,%EndDate] %PARAM_2
        echo     - %@Quote[%Name]   %@FileDate["%Name",w,4]
        set ToDelete=%ToDelete %@Quote[%Name]
    enddo
   
    :: If no file dates match the criteria exist
    iff not defined ToDelete then
        echo ^nThere are no files to delete
        goto EndProgram
    endiff

    :: Unless we are in no-prompt mode, request confirmation from the user
    iff not defined NoPrompt then
        echo.
        Input /C /K"yn" /L1 Delete the above %@Fields[%ToDelete] files%@if[defined SimulationMode, (Simulated)]? [y/n]:  %%Confirmation
        echo.
    else
        :: If NoPrompt is set, it's an automatic confirmation
        set Confirmation=y
    endiff
   
    :: Proceed with the deletion
    iff "%Confirmation"=="y" then
        :: Loop through each file and delete it (if not in simulation model)
        echo  - Deleting:
        do i in /Q %ToDelete
            echo     - %i %@if[defined SimulationMode, (Simulated)]
            iff not defined SimulationMode then
                del /Q /R %i
            endiff
        enddo
    endiff

    :: Exit the script
    :EndProgram
    EndLocal
    echo.
    quit


    :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    :: Subroutines
    :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    :Usage
        echo :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
        echo :: RemoveAfter DaysToKeep FilePattern
        echo ::
        echo :: Remove all files of the given pattern older than the Days provided.
        echo ::
        echo :: Note, today's date is considered day 1, so if you put a 1 as the days to keep it
        echo :: remove all files older than today's date.
        echo ::
        echo :: Also, only the "day" is considered, not the hours, minutes or seconds.
        echo :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
        echo.
        echo Usage:
        echo.
        echo RemoveAfter [-t] [-h] [-n] [-s] [-d] NumDays FilePattern
        echo.
        echo Parameters:
        echo   NumDays:     The number of backup days to keep.  Today is day 1
        echo   FilePattern: Process files that follow the provided pattern
        echo.
        echo Options:
        echo   -d:  Enable Debug Mode to show debugging output
        echo   -h:  Show this usage information
        echo   -n:  No prompt. Do not prompt for confirmation, just delete (dangerous)
        echo   -s:  Simulation mode. Run normally, but do not actually delete anything
        echo   -t:  Generate test data and exit. Useful for my testing
        echo.
        echo Examples:
        echo   RemoveAfter -s 3 Backup-*.rar
        echo   RemoveAfter -n 200 c:\MonthlyBackups\*.zip
       
        goto EndProgram
    return


    :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    :: Generate test data with one file per day descending
    :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    :GenerateTestData
        set TestDir=.\test
        set TestBaseName=Test
        set TestExt=tst
        set TestDays=60
        set OrigDir=%_CWD

        :: Create the test directory if needed
        iff not exist %TestDir then
            md /s %TestDir
        endiff

        *cdd %TestDir

        echo Generating Test Data in %TestDir
        echo        FileName          FileDate
        echo        ---------------   ----------
        do i=1 to %TestDays by 1
            set n=%TestBaseName-%@Random[100000,999999].%TestExt
            set d=%@MakeDate[%@Eval[%@Date[%_Date]-%@Dec[%i]],4]
            echo   %@Format[03,%i]: %n : %d
            touch /q /c /D%d %n
        enddo

        :: Head back to starting directory
        *cdd %OrigDir

        :: End Program
        goto EndProgram

    return
}
 
Last edited:
Here's another approach:

Code:
@echo off
*setlocal
*unalias *

rem     This script deletes any files over two weeks old from
rem     the user's temp directory and C:\WINDOWS\TEMP.

set n=14

alias purge=`if .%1 ne . if isdir %1 pushd %1 && ( del /[dc-%n,1980-01-01] /s /e /x /y /z * %+ popd )`

purge "%temp"
purge "%systemroot\temp"

endlocal
quit

The date range in the DEL command, line 10, does most of the work. /[DC because I'm interested in when a temp file was created, not when it was last written to or last read. An offset in the first date is relative to today's date, so a -1 means yesterday; -14 is two weeks ago. And I want my date range to end with that date, not to start with it, so I specify an impossibly early date (January 1, 1980) as the second date; if the dates are out of order, TCC automatically swaps them for us.

Changing to the top-level directory (PUSHD in this example) prevents DEL /X from removing the top-level directory, should it wind up completely empty.
 
Just a quick note that I've updated the code in the original post if anyone is using it.
 
Hi, I find this very useful, thank you !

192.168.100.1 192.168.1.1

(Formatting adjusted for legibility.)

You do understand that those are non-routable addresses, right? Nobody outside your own private network can access them. People can't see them. Search engines can't index them.

I will continue to delete these little advertisements, because of the sneaky and underhanded way you keep trying to smuggle them in. But even if I let them remain, they won't do you or anyone else any good. Because those are non-routable addresses.
 
Back
Top