Extracting Parts of a File Name
It is very common in batch file programming to need just part of a file name. I make use of a number of approaches, depending on the circumstances. One of my earliest approaches uses the standard FC.EXE utility.
  Using the FC.EXE Utility
For example, I took this question from a news group sometime ago.


Question:
I would like to apply pkzip to each file in a dir, maintaining the original filename minus extension in the zip. ie misc.dat -->> misc.zip stars.tif -->> stars.zip The problem: How can you extract the initial part of a filename without the extension?

I provided an approach I often use that is built around DOS's FC.EXE utility.


Answer:

Here's one way that I find useful. It uses the DOS FC.EXE utility.

@echo off %2 if [%1]==[] %0 *.* for %%v in (%1) do call %0 %%v goto:Parse for %%v in (attrib goto:End) do %%v -h *.zip :Parse fc %1 *. /lb0 > compari}g.bat echo pkzip -a %%4 %1 > comparing.bat for %%v in (compari}g del) do call %%v compari?g.bat attrib +h *.zip :End You can either call this program with no input arguments or with a filespec. Without an input, the procedure will operate on all the files in the currently active directory. With a filespec (which can include wildcards), the batch will process the matching files only.
FC is used here in an unconventional way. It isn't being used to compare two real files. Rather, the normally extraneous informaton generated by FC as it runs is providing the desired function. Specifically, the text string that describes the progress of the comparison contains the valuable bits of information needed for this application. FC very cooperatively parses the file name using the DOS asterisk wildcard character. Using the 'two file' processing method discussed eleswhere, it is a simple matter to collect the parsed result.

The particular question wanted the first part of the file name, but the same concept can extract the extension instead. In that case, the FC line would become ...

  fc %1 .* /lb0 > compari}g.bat

Of course, the second part of the process, implemented in COMPARING.BAT, would also be adapted to make use of the extension, say ...

  echo set Ext=%%4> comparing.bat

In addition to extracting the full file name, less the extension, this approach can also extract any number of characters. Say the first four characters of a file name and the extension are desired, then the FC line would look like this ..

  fc %1 ????;.* /lb0 > compari}g.bat

and the COMPARING.BAT file could be constructed something like ...

  echo set First=%%4> COMPARING.BAT
echo set Ext=%%5> COMPARING.BAT

Collecting all of these thoughts into a more generalized procedure to demonstrate the concept gives the batch file, FILENAME.BAT, below.
:: FILENAME.BAT - A procedure to manipulate an existing file name. :: :: Tom Lavedas <lavedas@pressroom.com> :: http://www.pressroom.com/~tglbatch/ @echo %dbgf% off %4 if [%1]==[] for %%v in (echo goto:End) do %%v Required filename missing. %4 if [%2]==[] %0 %1 Result *. %4 if [%3]==[] %0 %1 %2 *. %4 > %ram%.\comparing.bat echo %%5 %0 %1 %2 %%4 :: %4 >>%ram%.\comparing.bat fc %1 %3 /lb0 %4 comparing 1 2 3 4 :: del %ram%.\comparing.bat set %2=%3 :End
  Using the REName Command
There are other ways I have seen. One of the best makes use of the RENAME (REN) command to remove the extension. The most significant challenge for this approach is stripping the drive and directory information from a fully qualified filespec. This format results from 'dropping" a file onto a batch procedure or shortcut, which is a very useful way of delivering the file name to the procedure.

The trick I use is switch the active directory context to reference that of the supplied file name. This is easily done with just two lines of code ...

  %1\
cd %1\..

or in a single line ...

for %%v in (%1\ cd) do %%v %1\..

Then it is a simple matter to use a trick I picked up on the web, specifically to change the name of the file to be one without any extension using ...

  ren %1 *.

The stripped file name is collected into an environment variable with a FOR statement, something like ...

  for %%v in (*.) do set {FileName}=%%v

One more tricky part - restoring the original name to the file. RENAME can't do the job, because it cannot have a full filespec as its second parameter. That is, ...

  ren *. %1

causes an error, because the string in %1 is a full filespec. But all is not lost. There is a standard utility that can do the job - MOVE.EXE, as in ...

  move %{Filename}%. %1 > nul

It is necessary to provide a name without a wildcard or MOVE will create a directory having the original file name and move that file (sans extension) into the newly created subdirectory. Fortunately, providing the exact file name to be used, rather than a wildcard specification, causes MOVE to act as desired and rename the file instead.

Tying it all together into a batch procedure with a little extra checking to be certain files named without an extension don't gets renamed, gives ...

:: GetName.BAT - A procedure to manipulate an existing file name. :: :: Tom Lavedas <lavedas@pressroom.com> :: http://www.pressroom.com/~tglbatch/ @echo %dbgf% off if [%1]==[] for %%v in (echo goto:End) do %%v Required filename missing. for %%v in (%1\ cd) do %%v %1\.. if exist *. ren *. *.!@# ren %1 *. for %%v in (*.) do set {FileName}=%%v move %{FileName}% %1 > nul if exist *!@# ren *.!@# *. %; For example ;% echo. File Name: %{FileName}% %; For example ;% pause :End

  Extracting the Extension Instead

Having only the file name might be sufficient in many applications, but sometimes its the extension that is needed. The extension can be extracted fairly easily using many of the same techniques. Renaming the file is still the heart of the solution, but a special name is required as illustrated in the GetExt.BAT procedure below. The trick is to use a dummy name bracketed by percent signs. Such a name will disappear when a statement containing it is executed in a secondary batch procedure. This is exactly what happens in the 'GetExt' procedure.
:: GetExt.BAT - A procedure to extract the extension of an existing file. :: Tom Lavedas <lavedas@pressroom.com> :: http://www.pressroom.com/~tglbatch/ @echo %dbgf% off if [%1]==[] for %%v in (echo goto:End) do %%v Required filename missing. for %%v in (%1\ cd) do %%v %1\.. ren %1 %%dummy%%.* > {t}.bat for %%v in (%%dummy%%.*) do echo set {Ext}=%%v for %%v in ({t}.bat del) do call %%v {t}.bat ren %%dummy%%.* {{dummy}}.~!@ move {{dummy}}.~!@ %1 > nul %; For example ;% echo. Extension: %{Ext}% %; For example ;% pause :End

  Finding the Path Part of the Name

Finally, just to be complete, it is sometimes necessary to know what directory the file is stored in. This is easily done using the technique described in the ANSI Helper article along with the approach used here to switch the context of the current active directory as shown in the GetPath.BAT procedure below.
:: GetPath.BAT - A procedure to extract the path information of an existing file. :: Tom Lavedas <lavedas@pressroom.com> :: http://www.pressroom.com/~tglbatch/ @echo %dbgf% off if [%1]==[] for %%v in (echo goto:End) do %%v Required filename missing. for %%v in (%1\ cd) do %%v %1\.. > {a}.bat echo @prompt set {FilePath}=$p > {b}.bat %comspec% /e:2048 /c {a}.bat for %%v in ({b}.bat del) do call %%v {?}.bat %; For example ;% echo. File Path: %{FilePath}% %; For example ;% pause :End




Top | General Notes | Homepage