Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Nesting FOR IN DO statements in Windows 9x with Win95cmd.exe

3 views
Skip to first unread message

William Allen

unread,
Mar 2, 2002, 11:47:41 AM3/2/02
to
======Nesting FOR IN DO loops in Windows 9x with Win95cmd.exe

With a certain amount of %%effort%% you can nest FOR IN DO
statements in Windows 9x with multiple COMMAND shells, thus
(and there is only meant to be one line following the @ECHO OFF
but it will wrap in transmission):

====Begin cut-and-paste (omit this line)
@ECHO OFF
for %%j in (0 1) do command/c for %%%%k in (0 1 2 3) do command/c for %%%%%%%%%%%%%%%%n in (a b) do ECHO.%%%%%%%%%%%%%%%%n
echo.%%j=tens %%%%k=units

====End cut-and-paste (omit this line)
Cut-and-paste text between the ==== lines into file with extension .BAT
(and suitable base name). Lines that don't begin with two spaces have
wrapped accidentally. The code sample is purely for demonstration and
study purposes. It was written/tested in the Win9x GUI.

(Note: the next depth of nesting requires 32 x % symbols)

However, if you use a Batch Subroutine called with a Win95cmd protocol
(see Note below re:Win95cmd) you can very easily nest FOR IN DO
statements, thus:

====Begin cut-and-paste (omit this line)
@ECHO OFF
IF (GOTO:)==(%1) %1%2 (Subroutine handler)
:: Simple demo of triple-nested FOR IN DO
win95cmd /c %0 GOTO: _TEST

GOTO EOF (=Subroutine code follows=)
:_TEST (Usage: CALL %0 GOTO: _TEST)

for %%t in (0 1) DO (
ECHO. Change Tens digit
for %%u in (0 1 2 3) DO (
for %%f in ("" " ") DO (
ECHO.%%~f %%t=tens %%u=units
)
)
)

:EOF (End-of-file)

====End cut-and-paste (omit this line)
Cut-and-paste text between the ==== lines into file with extension .BAT
(and suitable base name). Lines that don't begin with two spaces have
wrapped accidentally. The code sample is purely for demonstration and
study purposes. It was written/tested in the Win9x GUI with the free
Microsoft Batch enhancer Win95cmd.exe merely placed in a folder in
the system PATH (for example C:\WINDOWS\COMMAND).

============Screen capture Windows 95
C:\WORK>w
Change Tens digit
0=tens 0=units
0=tens 0=units
0=tens 1=units
0=tens 1=units
0=tens 2=units
0=tens 2=units
0=tens 3=units
0=tens 3=units
Change Tens digit
1=tens 0=units
1=tens 0=units
1=tens 1=units
1=tens 1=units
1=tens 2=units
1=tens 2=units
1=tens 3=units
1=tens 3=units
C:\WORK>
============End screen capture

Note: the %%f [Space] string is just used to produce an
alternate indented effect. The %%~f is the "quote" suppression
for Win95cmd.exe string handling. It's quite suprising how powerful
FOR IN DO looping is with Win95cmd.exe - for help on FOR in
Win95cmd, with Win95cmd.exe in the path, simply type:
win95cmd /c for /?

--
(pp) William Allen

Note:
Win95cmd.exe is a free Microsoft batch enhancer for Windows 95/98/ME
users who are interested in learning and using some of the enhanced
batch language features in Win2000 (similar enhanced Batch features
are present in Windows XP). The worthwhile advantage of using Win95cmd
over idiosyncratic third-party Batch utilities is that it enables you
to learn and use (in Windows 9x) elements of the Batch syntax that
apply to Win2000 and WinXP should you go on to use/learn those OSes.

Win95cmd.exe file is available free as a single small ZIP from:
http://www.neuro.gatech.edu/users/cwilson/cygutils/unversioned/consize/

For all the uses illustrated in our posts it merely needs to be placed
in a folder in the system PATH, for example C:\WINDOWS\COMMAND

For general information about using it in Windows 95/98/ME and
syntax examples, see post:

Win95cmd Batch enhancer for Windows 95/98/ME users
http://groups.google.com/groups?selm=a04ecl$isbjh$1...@ID-55970.news.dfncis.de
Date: 23 Dec 2001

and for use of Win95cmd in Batch arithmetic, see post:
Batch arithmetic with the Win95cmd Batch enhancer
http://groups.google.com/groups?selm=9vdkh4$efe02$1...@ID-55970.news.dfncis.de
Date: 14 Dec 2001


Benny Pedersen

unread,
Mar 2, 2002, 5:44:05 PM3/2/02
to

"William Allen" <NgR...@mayfly13.fsnet.co.uk> wrote news:a5qvsi$9k0vc$1...@ID-55970.news.dfncis.de...


Hi cyber friends,

For some weeks ago, I figured out that all those percent can be reduced
to only two percent if numbers are used instead of letters. For example
%%9 instead of %%%%%%%%%%%%%%...Snipped...%%%%%a

so,

for %%j in (0 1 ) do command/c


for %%%%k in (0 1 2 3) do command/c
for %%%%%%%%%%%%%%%%n in (a b ) do ECHO.%%%%%%%%%%%%%%%%n
echo.%%j=tens %%%%k=units

became:

for %%1 in (0 1 ) do command/c
for %%2 in (0 1 2 3) do command/c
for %%3 in (a b ) do ECHO.%%3
echo.%%1=tens %%2=units

Moreover: How to split such loops:

@goto %1 j
:j
@echo off
for %%j in (0 1 ) do CALL %0 k %2 %3 %%j
goto end
:k
for %%k in (0 1 2 3) do CALL %0 n %2 %3 %%k
goto end
:n
for %%n in (a b ) do CALL %0 jkn %2 %3 %%n
goto end
:jkn
ECHO.%4
echo.%2=tens %3=units
:end

Benny Pedersen,
PS. Links:
Numb instead of letter; http://2dos.homepage.dk/batutil/NEWS5.HTM#six
Split the loops; http://2dos.homepage.dk/batutil/NEWS6.HTM#numb

The above page is trivial and long but there are a lot of
new discoverys between the lines and as usual without any
comments about that it may be new stuff. For examples:

How to perform several shifting in a FOR loop:

FOR %%! in (%2000 %2%300 %2%3%40 %2%3%4%5) do IF 0000==%%! SHIFT

The FOR Loop would like to "take a picture of the statement" before it
is executed, anyway, the variable was modified by the loop itself.

How to upper/lowercase in FOR loops using a slash (/).
(and much more...)

How to split a value of a variable named B into B1...Bn (as single digits):

Since B=9985, then

B1 would become 0
B2 would become 9
B3 would become 9
B4 would become 8
B5 would become 5

that could be done by the following 3 steps:
Set n length of E
Set B length as E
Set B1...Bn

like this:

@GOTO %1 Program
:Program
@ECHO off

SET B=9985
SET E=10007

ECHO..|CHOICE/c}%E%. Set n length of E >NUL
FOR %%} in (1 2 3 4 5) do IF errorlevel 77%%} SET n=%%}
:B
ECHO..|CHOICE/c}%B%. Set B length as E >NUL
IF NOT errorlevel 77%n% FOR %%c in (SET GOTO) do %%c B=0%B%

CALL %0 n 1 2 3 4 5 Set B1...Bn
FOR %%c in (SET GOTO) do %%c A=
:n
ECHO.%B%.|CHOICE/c.0123456789>NUL
FOR %%} in (0 1 2 3 4 5 6 7 8 9) do IF errorlevel 77%%} SET A=%%}
SET B%2=%A%
IF %2==%n% FOR %%c in (GOTO:EOF SET) do %%c B=
FOR %%%A% in (%%) do SET B=%%%B%
FOR %%c in (SHIFT GOTO:n) do %%c
:A Snipped...
:EOF

I simply haven't the time to see what is new or important
and my English isn't the best, so, I usual just write my
batch files without such comments ;-)


William Allen

unread,
Mar 3, 2002, 12:50:51 AM3/3/02
to
"Benny Pedersen" wrote in message
...snip

> For some weeks ago, I figured out that all those percent can be reduced
> to only two percent if numbers are used instead of letters. For example
> %%9 instead of %%%%%%%%%%%%%%...Snipped...%%%%%a
>
> so,
>
> for %%j in (0 1 ) do command/c
> for %%%%k in (0 1 2 3) do command/c
> for %%%%%%%%%%%%%%%%n in (a b ) do ECHO.%%%%%%%%%%%%%%%%n
> echo.%%j=tens %%%%k=units
> became:
>
> for %%1 in (0 1 ) do command/c
> for %%2 in (0 1 2 3) do command/c
> for %%3 in (a b ) do ECHO.%%3
> echo.%%1=tens %%2=units

Really Good Stuff, Benny :-)
As far as I am aware the %%Digit method is completely new,
and a really interesting discovery.

Just when there hardly seems any point reading this NewsGroup
anymore, you usually come up with something that makes the
time spent skimming through all the posts really worthwhile :-)

======

So, my original line which was too long to post normally without
wrapping (because it was more than 132 characters) becomes:

====Begin cut-and-paste (omit this line)
@ECHO OFF

for %%1 in (0 1) do command/c for %%2 in (0 1 2 3) do command/c for %%3 in (a b) do ECHO.%%3 %%1=tens %%2=units

====End cut-and-paste (omit this line)
Cut-and-paste text between the ==== lines into file with extension .BAT
(and suitable base name). Lines that don't begin with two spaces have
wrapped accidentally.

and the original line, which was 148+2[Space]s long, and very hard
to read, is now only 111+2[Space]s long.

--
(pp) William Allen


William Allen

unread,
Mar 3, 2002, 2:18:19 AM3/3/02
to
"William Allen" wrote in message

> "Benny Pedersen" wrote in message
> ...snip
> > For some weeks ago, I figured out that all those percent can be reduced
> > to only two percent if numbers are used instead of letters.
...snip

> Really Good Stuff, Benny :-)
> As far as I am aware the %%Digit method is completely new,
> and a really interesting discovery.

It's really a good idea the more I think about it, Benny, because
it makes nesting FOR loops in immediate mode really practical :-)

("Immediate mode"=when you just type commands at
the prompt rather than use them from a batch file).

For example, to answer questions in alt.msdos.batch,
I frequently need to create a bunch of files with different
names (typically in numeric patterns) and all with different
contents in each to test some renaming-or-whatever script.

I usually just use a regular expression in TextPad in a parallel
window (because it will always be open anyway if I'm writing
batch scripts), but the %%Digit method makes it easy for fast
typists to create lots of such files from the command line :-)

For example, the one-liner (it may wrap in some NewsReaders):

for %%1 in (0 1 2) do command/c for %%2 in (0 1 2 3 4 5 6 7 8 9) do command/c for %%3 in (">File%%1%%2") do ECHO.File %%1%%2%%3

creates 30 files called FILE00 to File00 to File29 all with different
contents related to their names ("File 00" to "File 29").
To review the contents quickly, use the immediate mode command:
for %%f in (file*) do type %%f

Note that in immediate mode _only_ you can shorten those
FOR IN DO lines by using only one % in the metavariable.
Specifically, that ALSO applies to the nested line, so that:

for %1 in (0 1 2) do command/c for %2 in (0 1 2 3 4 5 6 7 8 9) do command/c for %3 in (">File%1%2") do ECHO.File %1%2%3

works fine (though I normally use %% in both Batch and immediate
modes, for consistency).

Great idea Benny :-), makes Nested FOR IN DO really practical
for immediate mode command-line work in Win9x.

--
(pp) William Allen

Notes for Windows 9x Batch authors:
1)
That example command line is 128 characters long, and
obviously could be longer - you could use:
(0 1 2 3 4 5 6 7 8 9 a b c d e f) + (0 1 2 3 4 5 6 7 8 9 a b c d e f) + the rest
to write 256 Hex named files, all with different contents.
If you're working this way, you can SET T=(0 1 2 3 4 5 6 7 8 9 a b c d e f)
and expand it as part of the command with %T%, since Windows 9x
can use expanded variables in immediate mode.

As well as using DosKey to manipulate such lines, you can cut-and-paste
fragments within the DOS box (or from one DOS box to another) when
working with these sorts of lines. Remember that a cut-and-paste from
within a DOS box always has a carriage-return linefeed added, so the
result gets executed immediately. When building up a line that way,
insert say, a REM or :: to stop execution, and then use DosKey to
snip the REM or :: out again.

2) For applying these sorts of ideas in immediate mode in one
or more simultaneous DOS boxes, usually by far the best way
to learn/research Batch functions, consider using the full Win9x
command line capability (255 characters). To do this, add the
/u:255 switch to a SHELL= line in your CONFIG.SYS file in the
root folder (make sure you only have _one_ SHELL= line).

For example, I usually run with SHELL= in CONFIG.SYS as
(first two lines are functionless comments):

; 4096 bytes environment space; 255 character command line,
; and internal command line length of 1024 characters
SHELL=C:\WINDOWS\command.com C:\WINDOWS /e:4096 /p /u:255 /l:1024

For explanation of COMMAND.COM switches, just type
command /?


William Allen

unread,
Mar 3, 2002, 5:22:10 AM3/3/02
to
"William Allen" wrote in message
> > "Benny Pedersen" wrote in message
> > ...snip
> > > For some weeks ago, I figured out that all those percent can be reduced
> > > to only two percent if numbers are used instead of letters.

(***Benny, see my Note at the end)

Still very pleased with this syntax, Benny:-) it really does make
FOR IN DO nesting finally practical for immediate mode work!

Another example of complex file creation in immediate mode
(commands typed directly at the prompt):

First SET a variable in immediate mode
SET T=0 1 2 3 4 5 6 7 8 9

Then, in immediate mode:
========The line below is _one_ single immediate mode command line
for %1 in (%t%) do command/c for %2 in (%t%) do command/c for %3 in (Some Another) do command/c for %9 in (">") do echo. This is
%3file%1%2.txt%9%3File%1%2.txt
========The line above is _one_ single immediate mode command line

This one line then creates 200 files:
100 with names SomeFileNN.txt (NN from 00 to 99)
100 with names AnotherFileNN.txt (NN from 00 to 99)

The contents all differ, and reflect the file name:
The 100 Some* contain "This is SomefileNN.txt" (NN from 00 to 99)
The 100 Another* contain "This is AnotherfileNN.txt" (NN from 00 to 99)

(Note doubled %% would be needed for this syntax in a Batch file)

Welcome Back, Benny!

--
(pp) William Allen

Remember:


For applying these sorts of ideas in immediate mode in one

or more simultaneous DOS boxes (usually by far the best way
to learn/research Batch functions) use the full Win9x command


line capability (255 characters). To do this, add the /u:255 switch
to a SHELL= line in your CONFIG.SYS file in the root folder
(make sure you only have _one_ SHELL= line).

For example, I usually run with SHELL= in CONFIG.SYS as
(first two lines are functionless comments):

; 4096 bytes environment space; 255 character command line,
; and internal command line length of 1024 characters
SHELL=C:\WINDOWS\command.com C:\WINDOWS /e:4096 /p /u:255 /l:1024

For explanation of COMMAND.COM switches, just type
command /?

======Note for Benny Pedersen
In my opinion Benny, you really need to flag this %%Digit technique
in FOR IN DO statements as a _significant_ new discovery when you
mention it on your WebSite just in case people don't realise how useful
it can be. It finally makes nesting FOR IN DO statements in Windows 9x
a practical proposition.


0 new messages