[MD+F Multimedia News Reader]
The Rexx File - by Dr. Dirk Terrell

Summary: Dirk shows how to make a simple utility which recursively deletes files across nested directories. He also reveals a few tricks to searching command line arguments for switches and separating them from other arguments such as file masks.

This month I wrote a simple little program that extends what the OS/2 del command does. The del command, of course, deletes files and can handle wildcards like * and ? to match multiple files. One key capability it lacks, though, is a recursion option so that you can delete files not only from the current directory, but also from all the directories below the current one. So, I figured others might find a recursive delete function useful and wrote one I call recdel.

Because of the potential damage a deleting program can do, you should make the program default to prompting the user for each file being deleted and provide a command line switch that enables them to turn off the prompts. The recdel program does this by looking for a /F or /f switch to force the deletes to occur without prompting. If the user does not pass the switch to the program, it will ask for a confirmation for each file that will be deleted. To accomplish this, we will scan the command line for the switch and set a variable Confirm equal to 1 if confirmations should be requested. The command line scanning code looks like this:

Parse Arg Mask

If N<>0 then Do
   Mask=Strip(Overlay("  ",Mask,N))
At first we dump all of the parameters passed to the program in variable Mask with the Parse Arg instruction. Then we create another variable MaskUC which is Mask converted to uppercase so that we can catch /F or /f. We then use the Pos() function to see if /F is in the command line arguments. The variable N will be 0 if it is not present and some non-zero value (the location in MaskUC where it is found) if it is present. If it is non-zero, then we need to strip it out of variable Mask since we want Mask to contain the search mask files that we want to delete, *.chk for example. As usual, there are many ways to accomplish this. We'll do it with the Overlay() function. Overlay() allows you to replace part of one string with another. What we want to do is overlay two spaces on the string Mask where the /F or /f switch is. Since we used the Pos() function to determine the location, we have the information we need and we call the function like so:
Overlay("  ",Mask,N)
which means that two spaces will overwrite the contents of Mask at character position N which we got from the Pos() function. If we wrap a call to Strip() around the call to Overlay(), we will eliminate the extra spaces and have Mask contain only the search mask:
Mask=Strip(Overlay("  ",Mask,N))
Now that we have our search mask, we can use the SysFileTree() function to find all the files that we need to delete:
/* Register REXXLIB functions */
call rxfuncadd 'SysLoadFuncs','RexxUtil','SysLoadFuncs'
call sysloadfuncs
The "FSO" switches mean files only (F), scan subdirectories (S), and report only filenames(O). Stem variable File. will contain the filenames that mask our search mask and File.0 tells us how many files were found. So now all we have to do is loop through all of the files and delete them, asking for confirmation if needed. The loop code looks like this:
Do i=1 to File.0
   If Confirm=1 then Do
      Say "Delete" File.i||"? (y/n)"
      Parse Pull Answer
      If Translate(Answer)="Y" then
   If rc<>0 then
      Say File.i "could not be deleted."
end /* do */
We use the SysFileDelete() function to delete the files. The return code will be 0 if the file was deleted and non-zero if it could not be deleted. See the online REXX help for the meanings of the various non-zero return codes. All we do here is say that the file could not be deleted if the return code is non-zero.

And there you have it, a recursive delete command. There are some things you could add, such as a /Q switch to not report unsuccessful deletes, and a "Do you really want to do this?" prompt if the mask is * or *.*, especially if it is being executed from the root directory of a drive and the /F switch has been given. You could be in a heap of trouble very quickly if you're not careful with a script like this.

Download the source to this month's Rexx File: recdel.cmd

Copyright © 1999 - Falcon Networking ISSN 1203-5696
January 16, 1999