Printer Version | Table of Contents | Project Home Page |
Some background
I present two versions of this batch file. The older version is for use with DOS, the newer version for use with Win9X, Win2000, ME, NT, etc. The difference in the batch files is due to the fact that the newer versions of Windows (1) support long filenames, which FDATE does not, and (2) don't allow Fdate to use its /V feature to set environment variablesIntroduction
This batch file uses a crude, but effective, technique for giving a batch file the ability to call subroutines. If you've never seen something like this before, it is sort of mind-blowing. Here's some commentary on the more important lines involved in the technique.if (%1)==(SUBROUTINE) goto %2If the first parameter, %1, is "SUBROUTINE", then the batch file recognizes that it is being called for the purpose of executing one of its own subroutines. In such a case, it does a GOTO to the start of the requested subroutine. That is, it goes to the label whose name is in the second parameter.
for %%v in (*.*) do CALL %0 SUBROUTINE PROCESS! %%vIn a batch file, %0 contains the name by which the batch file was invoked. We use this fact to allow a batch file to call itself, regardless of what name the user has given to it.
GOTO ENDITWhen the mainline of the batch file is finished executing, we goto the end of the batch file. We MUST do this GOTO in order to avoid falling through into, and starting to execute, the first of the batch file's subroutines.
:PROCESS! shift shiftNote that when the batch file is called as a subroutine, and the batch file goes to the PROCESS! label, the values of the parms are:
%0 = [the name of the batch file] %1 = SUBROUTINE %2 = PROCESS! %3 = [name of the file to be processed]We shift all the parameters to the left twice, to move the parameter(s) into what we think of as the proper places for parameters to the subroutine.
%0 = SUBROUTINE %1 = PROCESS! %2 = [name of the file to be processed]After the second SHIFT command:
%0 = PROCESS! %1 = [name of the file to be processed]Now %1 contains what we think of as the proper parameter(s) to the subroutine. In this case, %1 contains the filename that we want the subroutine to process.
.CODE........:@echo off :: A newer version, for use with Windows 9X, Win2000, NT, etc. :: if (%1)==(SUBROUTINE) goto %2 cls :: set the number of days in the past. if this value is not passed :: in via parameter %1, it defaults to 3 days set NumDays=%1 if (%NumDays%)==() SET NumDays=3 echo ------------------------------------------------------------------ echo PROCESSING FILES CREATED MORE THAN %NumDays% DAYS AGO echo ------------------------------------------------------------------ :: Note the use of ~s in the variable reference. :: This causes the use of the short (8.3) filename, since Fdate cannot :: handle long filenames. for %%I in (*.*) do CALL %0 SUBROUTINE PROCESS! %%~sI echo ------------------------------------------------------------------ echo END OF PROCESSING echo ------------------------------------------------------------------ :: CLEANUP set NumDays= set DaysOld= set Comparison= GOTO ENDIT :PROCESS! shift shift :: get difference in days between filedate and today. :: Note that /B parm (which is omitted) defaults to today's date. Fdate /fdif /A%1 /IF /p"set DaysOld=" >temp.bat call temp.bat :: compare DaysOld to NumDays Fdate /F#comp /A%DaysOld% /B%NumDays% /p" set comparison=">temp.bat call temp.bat :: the following line will DISPLAY THE NAME AND AGE OF :: any file for which %DaysOld% is greater than %NumDays% :: -------------------------------------------------------------- if (%comparison%)==(GT) echo %1 is %DaysOld% days old. :: EXAMPLE (to activate this routine, remove the REM from column 1) :: the following line will COPY TO AN ARCHIVE SUBDIRECTORY :: any file for which %DaysOld% is greater than %NumDays% :: ----------------------------------------------- :: if (%comparison%)==(GT) COPY %1 C:\ARCHIVE\*.* :: EXAMPLE (to activate this routine, remove the REM from column 1) :: the following line will DELETE :: any file for which %DaysOld% is greater than %NumDays% :: ----------------------------------------------- :: if (%comparison%)==(GT) DEL %1 :: fall through to endit :endit
@echo off :: An older version, for use with DOS :: if (%1)==(SUBROUTINE) goto %2 cls :: set the number of days in the past. if this value is not passed :: in via parameter %1, it defaults to 3 days set NumDays=%1 if (%NumDays%)==() SET NumDays=3 echo ------------------------------------------------------------------ echo PROCESSING FILES CREATED MORE THAN %NumDays% DAYS AGO echo ------------------------------------------------------------------ for %%v in (*.*) do CALL %0 SUBROUTINE PROCESS! %%v echo ------------------------------------------------------------------ echo END OF PROCESSING echo ------------------------------------------------------------------ :: CLEANUP set NumDays= set DaysOld= set Comparison= GOTO ENDIT :PROCESS! shift shift :: get difference in days between filedate and today. :: Note that /B parm (which is omitted) defaults to today's date. Fdate /fdif /A%1 /IF /VDaysOld :: compare DaysOld to NumDays Fdate /F#comp /A%DaysOld% /B%NumDays% /Vcomparison :: the following line will DISPLAY THE NAME AND AGE OF :: any file for which %DaysOld% is greater than %NumDays% :: -------------------------------------------------------------- if (%comparison%)==(GT) echo %1 is %DaysOld% days old. :: EXAMPLE (to activate this routine, remove the REM from column 1) :: the following line will COPY TO AN ARCHIVE SUBDIRECTORY :: any file for which %DaysOld% is greater than %NumDays% :: ----------------------------------------------- :: if (%comparison%)==(GT) COPY %1 C:\ARCHIVE\*.* :: EXAMPLE (to activate this routine, remove the REM from column 1) :: the following line will DELETE :: any file for which %DaysOld% is greater than %NumDays% :: ----------------------------------------------- :: if (%comparison%)==(GT) DEL %1 :: fall through to endit :endit