Batch Files: Processing Characters in a Line

If you have Windows 95, you can use CHOICE. If you have DOS 5 or 6, you can use FOR as well. If you have any common sense, you'll use Basic. 

FOR Since it won't work on Windows 95, I'll cover it here just enough to allow you to understand it so you can convert any old code you might run across. It seems that an undocumented quirk of FOR was that any text in the "set" following a slash would be interpreted as two items: The character following the slash was one item, while the remainder of the word was another item:

Microsoft(R) MS-DOS(R) Version 5.00
(C)Copyright Microsoft Corp 1981-1991.

E:\>for %x in (/one two) do echo %x

E:\>echo o

E:\>echo ne

E:\>echo two

Notice how the word "one" was split into two parts, "o" and "ne". Using this quirk allowed words (file names, times, dates, etc.) to be picked apart character-by-character. Unfortunately, like all quirks, bugs, and undocumented features, there was no guarantee it would be the same on subsequent releases. Check out the different behavior under Windows 95:
Microsoft(R) Windows 95
   (C)Copyright Microsoft Corp 1981-1995.

E:\>for %x in (/one two) do echo %x

E:\>echo /ONE

E:\>echo two

Windows 95 now capitalizes everything following a slash. Another quirk. Take advantage of this capitalization only if you don't mind all your code failing on the next release of DOS.

CHOICE Using choice to extract individual characters will work on all DOS versions.
School time! Type this at a DOS prompt:
choice /c12345
What you get is
which is a demo of magic! (Go ahead and press 1,2,3,4, or 5) Choice has inserted delimiters (Commas in this case. Other delimiters are spaces, semicolons, and equals signs) between all our arguments. Well, almost. We need extra delimiters to separate the 1 and 5 from the brackets. So do this:
choice /c=12345=
Notice I used equals signs. Most people use semicolons. No real difference. You get this:
Big progress. Now comes trick #2. Choice allows you to specify a prompt. You just add it to the end of the choice line and it shows up at the beginning of the output. Try this simple example:
choice /c12345 Pick a number
You get this:
Pick a number[1,2,3,4,5]?

But we will use the prompt as a way to get a batch file name at the beginning of the line. Building on our previous example:
choice /c=12345= test.bat=
Which gives this:
Notice the equals sign after the batch file name? For increased readability, you should replace it with a space. But I can't show a space at the end of the line! It works either way (space or equals).

Next trick is to stop choice from hanging waiting for your keypress. We can just echo in one of the choices. To make it truly generic, we'll use the equals sign (since 12345 will be replaced by REAL data later on):
echo = | choice /c=12345= test.bat=

We now have a perfectly good command line. Let's go ahead and put this line into a batch file:

echo = | choice /c=12345= test.bat > temp.bat
Notice how I used a space after my "test.bat" instead of an equals sign. Our generated temp.bat will contain:
test.bat [=,1,2,3,4,5,=]?

Now let's create a simple test.bat. Try this:
@echo off
if [%1]==[] goto end
echo %1
goto start

All this test.bat does is display the arguments in order. A great generic test program any time you are working with multiple arguments! When we run our TEMP.BAT, it will run TEST.BAT and give us this result:
The first displayed argument is "[", the second is "1", and so on. So your TEST.BAT could refer to %2 through %6 to display the first five characters.

No we are ready to go fully generic. We'll assume we'll have a batch file that will be passed a word as an argument. The word will be %1 (the first argument). So we do away with the 12345:
echo = | choice /c=%1= test.bat > temp.bat
So you just put the above line in a simple batch file and call it with a word (one word with no spaces) as an argument. It will create a temp.bat which will run a test.bat. You build your test.bat to do whatever you want with the individual letters in the word.

Lost? Look at the site map.

Bad links? Questions? Send me mail.

Ask Jeeves