Finding and Deleting Files By Ken Johnson In last the last session, we looked at several ways of finding and managing files scattered throughout your hard disk. These included: þ The TREE command to view a graphical representation of your subdirectory structure. For example: TREE C:\. þ The DIR /S command (DOS 5.0), to display full path and file names for files in the current directory and child subdirectories matching a filespec. For example: DIR C:\*.BAK /S /B. þ The ATTRIB /S command (DOS 3.3 and above) to search through subdirectories for files matching a certain filespec. For example: ATTRIB C:\*.BAK /S. [Please note a correction for August's article: the /S switch was added to the ATTRIB command in DOS 3.3, not 5.0.] þ CHKDSK /V to display all files on the disk (including hidden files), then using the FIND filter to output only those files matching a specified string. For example: CHKDSK C: /V | FIND ".BAK". The example we used in the last session was finding all the backup files (*.BAK) on the C: drive. This month we will continue that example, but this time looking at ways to both find and delete those files. Once you have gotten a listing of your *.BAK files using one of the techniques above, you may want to delete those to free up disk space. The DEL and ERASE commands do not have a way to delete across multiple subdirectories at once -- probably a good thing for most of us! However, we can use the techniques discussed in last month's column to find these files, then with just a little more work automate deleting them. For example, you can output the results of the DIR /S /B command into a batch file, and edit that file to include the DEL command at the beginning of each line. Then by simply running the batch file, all the *.BAK files will be deleted. The following three steps would accomplish this (remember though that the /S /B switches are only supported in DOS 5.0; we'll see a little later how to do this with earlier versions of DOS): DIR C:\*.BAK /S /B > KILLBAK.BAT EDIT KILLBAK.BAT KILLBAK Let's take a closer look at each of these three steps. The first line, DIR C:\*.BAK /S /B > KILLBAK.BAT will output the directory listing into a file called KILLBAK.BAT. Since we are using the /S /B switches on the DIR command, the listing will include only the file names, with the full path specified. By outputting to a file with a .BAT extension, we identify that file to DOS as one containing executable commands and programs. The second line, EDIT KILLBAK.BAT will run the DOS 5.0 Editor and load the KILLBAK.BAT file. Simply go down the list of files, and insert DEL in front of each name. You might also want to put @ECHO OFF as the first line in the file, which will suppress the display of the deletion messages as they execute. Here is a quick trick when using EDIT: use the Search and Replace feature to replace each "C:\" with "DEL C:\", since you know that each filename includes the full path beginning with C:\ (assuming of course you're working with the C: drive). Make sure you are at the top of the file before starting. Hold down the ALT key, and press the letter S. This drops down the Search Menu. Press C for Change, and EDIT brings up the Change dialog box. For Find What:, enter C:\. For Change To:, enter DEL C:\. Then Tab down (or use the mouse) to select . Now simply save the file and exit. The final line, KILLBAT runs the batch file, which will delete the .BAK files on the disk. If you don't have DOS 5.0, you can do something similar using CHKDSK /V and a text editor of your choice. For example, if you use Qedit (Q.EXE) as your text editor, the commands would be: CHKDSK /V | FIND ".BAK" | SORT > KILLBAK.BAT Q KILLBAK.BAT KILLBAK The use of the SORT filter here is not really necessary, but it is convenient to have the names in order when editing them. As we saw last month, CHKDSK doesn't necessarily output the names of files in subdirectory order. By using the SORT filter, all files in each subdirectory will be grouped together. Anytime you enter a group of DOS commands repetitively, consider putting those commands in a batch file. Let's extend this "find and delete" procedure to do general housekeeping of the hard disk. We'll create a generic batch file that will find and delete files that match any filespec you specify. To make it even more interesting, let's have the batch program process up to three filespecs to delete. Before looking at this batch program, let's review a little about batch files and the batch commands. A batch file is simply a text file that contains DOS commands and/or programs to run. Batch files can be identified by their ".BAT" file extension. To execute a batch file, you simply enter the name of the file without the extension. DOS will look at each line in the file and execute the command or program it finds there -- just as if you had typed them in yourself. One powerful feature of batch files is the ability to include parameters that are passed to the batch file when it executes. When DOS executes a batch file it examines the command line, dividing what you've entered into discrete elements. DOS then assigns these elements to up to ten variables, or parameters. These parameters are in the form %N, where N is a number from 0 to 9. As a batch file executes, each occurrence of %N is replaced by the corresponding string from the DOS command line. %0 corresponds to the first thing you typed, which is always the name of the batch file itself. One word of warning when writing "destructive" batch files -- programs that do nasty things like deleting many files. Carefully check the commands before running. Print out the batch file and painstakingly review it. Make sure you don't, for example, mistake DEL for DIR, or *.TXT for *.TMP. You may want to make a test floppy disk, including all appropriate files and subdirectories, and test the batch file on the floppy first. You can use the XCOPY command with the /S and /E switches to copy files and subdirectories. /S copies matching filespecs in their subdirectories. /E copies subdirectories even if there are no matching files in those subdirectories; the subdirectories will be empty. For example, to copy all your *.BAK files and replicate the hard disk subdirectory structure on A:, you would use: XCOPY C:\*.BAK A: /S /E. The Batch programming "language" is made up of just a handful of commands: ECHO -- suppresses the display of normal DOS messages during the execution of a batch file (ECHO OFF), and optionally display messages to the user (ECHO "message"). REM -- is a REMark statement, which does not display when ECHO is off. PAUSE -- temporarily stops the batch file execution until the user presses a key, and displays the famous "Press any key when ready . . ." message. GOTO -- jumps execution to another part of the batch file, identified by a unique label (for example, GOTO END). The label must start with a colon and be the first thing on the line (:END). IF -- conditional execution of a command or program, based on one of three conditions. IF can check whether a file exists (IF EXIST BUDGET.DBF), whether two strings are equal (IF %1==KEN), or the number of the DOS ERRORLEVEL code (IF ERRORLEVEL 4). FOR -- variable IN (list) DO command -- repeats a DOS command multiple times, replacing a variable with values from a list. SHIFT -- changes each batch parameter to the value of the next higher one (e.g., %1 becomes %2, %2 becomes %3, and so on). This allows you to write batch programs that can process more than 10 parameters. CALL -- (DOS 3.3 and above) -- used to execute one batch file from inside another. The @ Operator -- (DOS 3.3 and above) -- a one-line-only version of ECHO OFF; when prefixed to any DOS command, that command won't display on the screen. It's most frequently used with ECHO (i.e., @ECHO OFF) to prevent the echo off itself from being seen on the screen. You'll see several of these batch commands used in our housekeeping batch file, called CLEANUP3.BAT. Here it is: @ECHO OFF REM CLEANUP3.BAT REM Takes up to 3 filespecs and deletes them REM Note: this file requires DOS 5.0 REM IF "%1!"=="!" GOTO NONAME ECHO @ECHO OFF > KILLEM.BAT DIR C:\%1 /S /B >> KILLEM.BAT IF "%2!"=="!" GOTO EDITNOW DIR C:\%2 /S /B >> KILLEM.BAT IF "%3!"=="!" GOTO EDITNOW DIR C:\%3 /S /B >> KILLEM.BAT :EDITNOW EDIT KILLEM.BAT ECHO. ECHO If you do NOT want to run the KILLEM batch file ECHO you just edited, press CTRL-C now. Otherwise, PAUSE CALL KILLEM.BAT ECHO. ECHO These filespec(s) have been deleted: %1 %2 %3 ECHO. GOTO END :NONAME ECHO. ECHO Please enter up to 3 file specifications, ECHO for example: CLEANUP3 *.BAK *.TMP *.$$$ ECHO. :END Let's take a closer look at this batch program. It allows you to enter up to three filespecs to delete on the command line. These filespecs become the replaceable parameters %1, %2, and %3. Line 6 of the batch program, IF "%1!"=="!" GOTO NONAME checks to see if any filespecs were entered at all. If not, then %1 is blank and the statement "!"=="!" is true. The batch file branches to the NONAME label, where lines 26 & 27 display a message to the user asking them to enter up to three filespecs on the command line. The batch program then ends. (By the way, "ECHO." is a technique for outputting a blank line. The period represents a Line Feed; echoing it simply displays a blank line. This way, separate messages on the screen are spaced out and easier to read.) If at least one filespec was entered, processing continues to the next line. We know that we are going to be outputting filenames, so we'll do a little trick. Line 7, ECHO @ECHO OFF > KILLEM.BAT outputs the text string "@ECHO OFF" into the KILLEM.BAT file by using the DOS ">" redirection symbol. This both creates the batch file to contain the file names to delete, and puts a "@ECHO OFF" as the first line in that file. It saves us from having to manually put in the @ECHO OFF command in KILLEM.BAT, or forgetting to put it in and having to watch all those delete commands execute. Line 8, DIR C:\%1 /S /B >> KILLEM.BAT processes the first filespec. %1 is replaced by the first filespec entered on the command line. The DIR command searches the entire C: drive (the /S switch) looking for that filespec. The results of the DIR command will include the full path and filenames (the /B switch), and will be appended to the KILLEM.BAT file. Notice that we use the ">>" symbol, which will append the output to the KILLEM.BAT file. If we had used the ">" symbol, it would have overwritten the existing KILLEM file (which contains the @ECHO OFF which we so cleverly put in!). Line 9, IF "%2!"=="!" GOTO EDITNOW checks to see if there was a second filespec entered. If not, "!"=="!" is true and the batch file jumps to the EDITNOW label. This is the part of the program where you will edit the KILLEM.BAT to include the DEL command in front of each filename. When a second filespec is entered, processing continues to line 10 where that filespec is processed. Just like before, the filenames will be appended to the KILLEM.BAT file. Lines 11 and 12 process the third filespec in the same way. If none is entered, %3 is blank and processing jumps to the EDITNOW label. If a third filespec was entered, it is processed by the DIR command and the results appended to the KILLEM.BAT file. Line 14 brings up the DOS 5.0 EDIT program and allows you to edit the KILLEM.BAT file. Again, this is where you will add "DEL" to be beginning of each filename line (don't forget the Search and Replace tip). You can also remove file names you don't want to delete, in case you've inadvertently included any files that you need to keep. Lines 16 through 18, ECHO If you do NOT want to run the KILLEM batch file ECHO you just edited, press CTRL-C now. Otherwise, PAUSE is a safety point that allows you to abandon the operation without deleting any files. The CTRL-C key combination will stop a batch file. The PAUSE key stops the execution of the batch file (with the "Press any key to continue" message) while you read the message. If you decide you don't want to delete the files in KILLEM.BAT, just press CTRL-C. To continue with the deletion, just press any key. Line 19, CALL KILLEM.BAT does the deletions. Control is passed to KILLEM.BAT; after it runs, control returns to this batch file (CLEANUP3.BAT) and processing continues at line 20. Line 21 displays a message telling you what filespecs have been deleted (remember that one of DOS' quirks is that there is no message after a deletion takes place). For example you wanted to delete *.BAK and *.KEJ files, this message would display: These filespec(s) have been deleted: *.BAK *.KEJ After the message is displayed, the program jumps to the END label, and the program ends. This is necessary to prevent the "NONAME" echo message from displaying. In the last two sessions we've looked at several techniques for finding and managing files, along with a few tricks along with way: CHKDSK /V to see hidden files, redirecting with >, >>, and |, viewing output with MORE and LIST, using the FIND and SORT filters, and putting it together in a batch file. Remember that as you expand your DOS knowledge, always be on the lookout for ways to integrate what you've learned and make your time with DOS more productive.