Creating and Processing Lists of File Names 

To get a list of all files of a certain type on your disk, use the DIR command with it's /s option to recursively search all subdirectories. Also use the /b option for the "bare" output to get JUST the file name (no header stuff). For example, to get a list of all Excel files on your C: drive:

dir /s /b c:\*.xls

If you want to save the results, just redirect the output into a file:

dir /s /b c:\*.xls > filelist.txt

If you only want files in a certain subdirectory (say all the text files in and under the Windows directory), just start there:

dir /s /b c:\windows\*.txt > filelist.txt

If you want just a list of directories, it's as simple as using the appropriate /ad DIR option:

dir /s /b /ad c:\*.* > directorylist.txt

Note that using the /s option with DIR will do two things: It searches all subdirectories AND it generates fully-qualified file names. Leave out the /s option to get JUST names.

The only problem with everything I tell you above is that the generated file list will be long file names. I REALLY REALLY hate long file names because they break all kinds of otherwise good batch code. About the only way to process a list of long file names is to quote them and the only pure DOS way to do that is to get the long name into the environment. Here's an example showing how to process a list of long file names this way.
 
FRAGMENT.TXT MAIN.BAT
set filename= @echo off 
:START 
copy fragment.txt + filelist.txt temp.txt > nul 
type temp.txt | find "set filename=" > temp.bat
echo call process.bat >> temp.bat
call temp.bat 
type temp.txt | find /v "set filename=" > filelist.txt 
copy filelist.txt nul | find "0" > nul
if errorlevel 1 goto START 
FILELIST.TXT PROCESS.BAT
C:\Program Files\faq.txt
C:\Received Files\msg.txt
C:\My Documents\report.doc
echo Processing "%filename%"
The big disadvantage here is tremendous disk activity. I won't go on with a description of the above example. Instead, see the generic description on Batch Sequential Processing of a List.


There is no simple way to create a recursive list of short file names (unless you reboot into DOS mode!), but this code will get the short names in a given directory:

lfnfor off
for %%x in (*.*) do echo %%x > filelist.txt

As long as you happen to be in a given directory, the undocumented TRUENAME command will give you the fully-qualified short file name of any file in that directory. Keep that in mind as you read the next two tidbits.

To change into a given drive, just add a trailing backslash to any fully-qualified file name and  execute the result. For example, either of these two lines would change to the C: drive.

"C:\Program Files\Acrobat\Acrobat.pdf\"
C:\PROGRA~1\ACROBAT\ACROBAT.PDF\

To change to a given directory, add a trailing backslash and a double-dot. For example, either of these will change to the C:\Program Files\Acrobat directory:

cd "C:\Program Files\Acrobat\Acrobat.pdf\.."
cd C:\PROGRA~1\ACROBAT\ACROBAT.PDF\..

The great part of having a list of short names is that it allows you several different ways to process. One of my favorite ways of working with short file names is to separate the name and extension parts. Since the DIR command normally does this, I use it:

@echo off
dir /a-d *.* | find "-" | find ":" > en#er.bat
echo.>> en#er.bat
type en#er.bat | date | find "Enter new date" | find "   " >> en#er.bat
echo @echo Name = %%3  Extension = %%4 > new.bat
copy c:\windows\command\loadfix.com enter.com
call en#er.bat
del enter.com
del new.bat

In the above example, I'll refer you to the Renaming LOADFIX.COM page for an explanation of why I use a "new.bat" and "loadfix.com". I've create a "stub" new.bat on-the-fly in the above example, but your new.bat would probably be a call to some other "process.bat" where the REAL work would be done.


But I have to be honest with you. If you don't have to write a big batch file, you shouldn't. Look, if you already have a list of files, you may be stuck using it. But maybe you can get away WITHOUT creating the list. If you just want to process certain files in a single directory, you should use the FOR command:

lfnfor off
for %%x in (*.xls) do call process.bat %%x

Yes, I assume there is a process.bat somewhere that will do something. If you have several directories you need to process, just duplicate the lines:

lfnfor off
for %%x in (c:\temp\*.xls) do call process.bat %%x
for %%x in (c:\windows\temp\*.xls) do call process.bat %%x
for %%x in (c:\windows\tempor~1\*.xls) do call process.bat %%x

Don't get forced into doing anything huge unless you absolutely have to.

Lost? Look at the site map.

Bad links? Questions? Send me mail.

Google
Yahoo
Ask Jeeves