Strange issue with FOR loop

May 26, 2008
537
4
I get unexpected results with this batch file:

Code:
@echo off

for %%a in (
123
234
345
456
) do (
grep %%a test.txt
)

TC doesn't run the grep command correctly, and then it also executes test.txt after each grep command, opening the file in Notepad. If I restructure it to look like this, everything works correctly:

Code:
@echo off

for %%a in (123 234 345 456) do (
grep %%a test.txt
)

CMD behaves correctly with both layouts. It seems TC has an issue when there are line breaks in the set.

I confirmed this on both 15.01.52 and 15.01.54.
 
May 26, 2008
537
4
I've used this syntax (with CMD) sometimes since XP, if not possibly Win2k. Surprisingly I must not have tried it in TCC until today.

I find it very convenient when I'm copying a list of something (server names, for instance) from Excel or some other location where there is one entry per line. With TCC I would be forced to join all the lines and put spaces between the entries. It would be great if TCC would support this CMD syntax.
 
May 26, 2008
537
4
I've not tried looking to see if it's documented, but CMD has supported the syntax since at least NT 4.0. I can try doing some searching but it may be an undocumented feature.
 
Dec 7, 2009
238
2
Left Coast, USA
Rex: it isn't documented that I know of (cmd.exe's "documentation" is strictly from hunger, at best).

The bit with the parens is just one of those things you stumble across and hack around with until it kinda sorta works, except when it doesn't.

I don't have any flavor of grep.exe here. For less sophisticated searches, when I don't want to fire up Perl, I make do with findstr.exe -- and this works ok (no sign of 'test.txt' trying to open itself in Notepad):

do string in /L 123 234 345 456
findstr.exe /i /m /c:"%string" test.txt
iff errorlevel == 0 then

:: do something here
else
:: do something else
endiff
enddo

I dispensed with 'for' a long time ago on realizing how much better 'do' is in so many ways. Egad, being able to dispense with 'for' and use 'do' is, IMO, one of the (many) huge "draws" of the whole 4NT/TCC system!

Though the example in the first message, above, does work in cmd.exe, that "command processor" has always had unpleasant bugs w.r.t. parens. Nest enough of 'em, and eventually you run across the bugs. All praise to 'do'...
 
Dec 7, 2009
238
2
Left Coast, USA
Here's an example of a truly fun obscure bug in cmd.exe that pertains to using parens in loops:

I always use "::" to begin comments. It's just that much less mess on the screen, compared with "REM". So one day at work, years ago, a co-worker had a batch file that kept failing miserably. She'd decided -- on my recommendation -- to make liberal use of the "::" alternative to "REM". She'd written a "for" loop that should have worked just fine. But: she started getting these miserable failures. The batch file was hardly rocket-science! Nobody could figure out why the thing didn't work. Then it occurred to me -- as stupid as it sounded:
there were a number of nested parens in this "for" loop -- and multiple lines. What if the "::" comments were the problem? YEP. When I added "REM" in place of "::", the stupid little batch file started working. Totally lucky guess. The other fun part? It didn't always fail with "::" inside the loop and inside the parens. It only failed sometimes.

How do I hate thee, cmd.exe? Let me count the ways...
 
May 26, 2008
537
4
I dispensed with 'for' a long time ago on realizing how much better 'do' is in so many ways. Egad, being able to dispense with 'for' and use 'do' is, IMO, one of the (many) huge "draws" of the whole 4NT/TCC system!
I hear what you're saying, but I work on soooo many systems that I often use CMD and syntax that works well with it. I was simply surprised that TCC did not support this syntax that CMD works just fine with.
 
May 20, 2008
3,515
4
Elkridge, MD, USA
Just because undocumented syntax seems to do what you expect on some systems, you cannot depend on it - you need to verify it after each OS update that it still behaves the same way (alternately, you can verify that neither CMD.EXE nor any API it uses was changed by the update...). Of course, if you use multiple systems, you need to test each one for its conformance to your expectations, which go beyond what its vendor claims...
 
Dec 7, 2009
238
2
Left Coast, USA
> CMD behaves correctly with both layouts. It seems TC has an issue when there are line breaks in the set.

You can at least cut your losses by getting rid of the line breaks and putting the set of strings into a single line. If there are so many of them that they make the .cmd file difficult to read at that point, consider using more than one "for" loop.

I came to so distrust cmd.exe, with its quirks w.r.t. parens and its damnable delayed-variable-expansion silliness, that except for the simplest possible kinds of "for" routines I took to doing it this way:

for %%A in (whatever goes here) do call :Some_Label %%A

In non-trivial batch files in which I'd MUCH rather use TCC syntax if at all possible: right at the top, a test -- is TCC running? If so, forget cmd.exe syntax entirely:

if "%_cwps%" NEQ "" goto Use_TCC

... a TCC-only version within the .cmd file. Or, an entirely separate .btm file that gets launched at that point.

If it's really better to have the "set" in question arranged one-item-per-line, you could ECHO the strings >> to a temporary text file and use "for /f" on the file. In any event, Steve Fabian is right that the undocumented behavior could change the next time there's an o.s. update. Then it seems to me the only way you'd find out would be if a bunch of your .cmd files started breaking. That'd be an unpleasant surprise...
 
May 26, 2008
537
4
Just because undocumented syntax seems to do what you expect on some systems, you cannot depend on it - you need to verify it after each OS update that it still behaves the same way (alternately, you can verify that neither CMD.EXE nor any API it uses was changed by the update...). Of course, if you use multiple systems, you need to test each one for its conformance to your expectations, which go beyond what its vendor claims...
I did verify it works as I expected all the way from NT 4.0 to Windows 2012. Seems pretty consistent to me!
 
May 26, 2008
537
4
You can at least cut your losses by getting rid of the line breaks and putting the set of strings into a single line. If there are so many of them that they make the .cmd file difficult to read at that point, consider using more than one "for" loop.
That's just it, sometimes I may have a couple hundred strings so joining them together in a single line would not work. Making multiple FOR loops is just a lame workaround IMO. I could put all the lines in a separate file and just reference the file itself in the FOR loop, but then I have two files instead of one.

In reality I'm just going to end up using CMD in cases like this instead of TCC.
 
May 20, 2008
11,411
99
Syracuse, NY, USA
Escaping the newlines will give the readability you want (but won't be CMD-compatible).
Code:
v:\> type ml.bat
@echo off
for %%a in (^
123 ^
234 ^
345 ^
456 ^
) do (
echo %%a test.txt
)

v:\> ml.bat
123 test.txt
234 test.txt
345 test.txt
456 test.txt
 
Dec 7, 2009
238
2
Left Coast, USA
> That's just it, sometimes I may have a couple hundred strings so joining them together in a single line would not work.

Probably not. Do you hard-code the batch files with the specific lists of strings?

> I could put all the lines in a separate file and just reference the file itself in the FOR loop, but then I have two files instead of one.

This never struck me as a terrible hardship, especially if I could create one (non-hard-coded) batch file and just create the input file on the fly, as need be. In which case, we're talking about two files only at the time the first batch file is created, plus the input file. After that, the batch file remains unchanged and you don't have to think about it again, right? Only the input file -- updated as need be on the fly -- has to change. If the list of strings doesn't have to be made by hand but can be generated within the batch file itself (no manual intervention by you, that is), then really there's only one file to consider -- in practical terms -- since you can have the batch file generate a temporary file and remove it when you're done. I don't mind if the solution looks a bit lame to someone else -- if I can keep it TCC-ish and not be forced to use .cmd syntax. Cmd.exe batch files might have improved marginally over the years, but it still strikes me that .btm files execute somewhat faster. So: hugely better command-set, faster execution... TCC 1, cmd.exe 0. But that's just me. : )
 
Similar threads
Thread starter Title Forum Replies Date
M Another possibly strange remote registry issue Support 5
R strange bug? Support 7
Jesse Heines Strange Line Wrapping Behavior Support 14
F strange results Support 9
M Strange error messages from TCC in FTP copy Support 7
forbin Strange handling of [nonbright] magenta background (v22) Support 2
N Fixed Strange dir behavior Support 6
vefatica REGDIR, strange error message Support 7
T WAD Strange Unexpected "features" in the Debugger Support 2
P Strange mouse behavior with list Support 2
vefatica Strange tcc.exception.log Support 7
vefatica A strange one Support 0
D Strange DO behavior with /O Support 5
Glenn Bowes Strange text at startup Support 5
Steve Pitts WAD Strange output from DEL of a non-existent directory Support 7
vefatica Big numbers, strange errors Support 1
aedthuio Strange... lpksetup Support 4
CWBillow dir /4 strange Support 2
MikeBaas Strange prob with %@replace.. Support 4
vefatica OT: strange files in %TEMP Support 10
Dan Glynhampton Documentation v15 help: Strange links in @INT topic Support 0
R WAD Strange output from "memory" command Support 1
M Yet another strange something re something called "@TCONVERT" Support 8
Roedy How to? Strange colours Support 9
M WAD Strange "Start" misbehavior... Support 10
vefatica Very strange console font corruption Support 3
Steve Pitts Strange problem with FREE Support 10
A strange error in alias Support 9
newgeekorder Debugger IDE - strange tab and parameter behaviour Support 1
Exolon Strange Prompt. Support 6
vefatica Strange folders Support 1
T Strange CPU value Support 3
J Strange error: unset /s Support 14
M Strange behavior... Support 2
CWBillow Strange happenings Support 2
B Strange handling of a .BAT file Support 5
vefatica Strange behavior reloading SHRALIAS sav files. Support 1
J ASSOC / FTYPE strange error message Support 3
D Strange crashes in @CRC32 and @MD5 Support 9
Charles Dye Strange output, here-doc redirection, TYPE, //UnicodeOutput=Yes Support 6
S Strange CHKDSK behavior Support 6
vefatica Strange results with CP 1252 Support 12
S Strange REN problem - non-English characters Support 3
dcantor Strange status in ACTIVATE command Support 0
cgunhouse TCToolBar /W Issue Support 2
G v28 Display Issue Support 7
Jay Sage Issue with CD_ENTER Alias Support 37
Jay Sage Issue with CD_LEAVE Alias Support 3
fpefpe How to? issue with % and evaluation Support 5
cgunhouse Standard User Account Issue Support 2

Similar threads