1.

Solve : Batch If inside For?

Answer»

For some reason my PROGRAM is blowing up when I try to nest a IF within a FOR loop. I've been working in C base languages for years and am just teaching myself how to write batches so some of the syntax has been a bit weird to adjust to.

I'm using this program to run through a list of .sql files and copy the ones with "PROD" found in them to another directory for review.

Thanks in advance.

for %%I in (*.sql) do (
find /n /i "PROD" %%I >> PROD_Check/PROD_Check_Lines.txt
if find "PROD" %%I (copy %%I PROD_Check)
echo 1 >> PROD_Check/i.txt
)I think this is what you're looking for:

Code: [Select]for %%I in (*.sql) do (
find /n /i "PROD" %%I >> PROD_Check/PROD_Check_Lines.txt
if errorlevel 0 (copy %%I PROD_Check)
echo 1 >> PROD_Check/i.txt
)

I couldn't decide whether the echo statement was part of the if. Based on your code, I determined it is not.

That got it to run, and it copied files, however I'm trying to copy ONLY the files that have PROD in them. Since techincally the find never comes across an error because finding nothing is not an error (at least I don't believe it is).

And yes you were correct that echo is not in the if, it is only in the for. Still dont know the standards for writing these yet .I found an alternate way to do what I was trying to do with this, however I still have been issues with nesting If's within For loops. Could someone post a nested If because I was told it could be my formatting, so I would like to compare.[edit] see belowQuote from: Grimbear13 on NOVEMBER 16, 2009, 07:15:03 AM

Since techincally the find never comes across an error because finding nothing is not an error (at least I don't believe it is).

Maybe the name "errorlevel" is misleading. Think of it as "exit code". Finding "nothing" is a result that the calling process needs to know about. Find, like most commands, always returns an errorlevel. It will be zero if the operation was successful (the string was found), and NONZERO if it was not.

In command scripts ("batch files") there is a problem (or a feature if you prefer!) with variables which are both created and expanded (read) inside a parenthetical structure such as a loop or a multiline IF. This is due to the way that cmd.exe operates when interpreting a script. In a nutshell, by default cmd.exe expands all variables at runtime and plugs them in where it finds their placeholders (those sections of text with percent %signs%). Variables whose value is not yet known (those created by a set command inside a loop or if block) will have null values inside that block. If the variable in question is an implicit one such as errorlevel, it will be zero regardless of the actual return code sent by the preceding program or command.

To get around this, from Windows 2000 onwards, NT scripting introduced delayed expansion.

It involves two things:

1. Before the code in question, most often at the start, after the @echo off line, include this line

setlocal enabledelayedexpansion

2. The relevant variables have a modified syntax - you use exclamation marks or points (!) and not percent signs (%).

Now for the question of errorlevel.

In MS-DOS, programs returned a code called errorlevel (or ERRORLEVEL if you like) which you could test for. Some programs or commands merely returned zero (no error) or some nonzero value (an error occurred). Others returned specific values which had meanings. It was a byte; you could have an errorlevel from 0 to 255. NT scripting post win2K uses a 16 bit word.

The IF ERRORLEVEL format with no percent signs is retained in NT scripting, but it has a non-obvious catch. for nonzero errorlevels, IF ERRORLEVEL N [command] means "If the errorlevel is N or greater [command]". THUS testing for different errorlevels had to be done in descending order to work properly

if errorlevel 7 [whatever]
if errorlevel 6 [whatever]
if errorlevel 5 [whatever]

In loops, and other parenthetical structures, you should use the post-Windows 2000 %errorlevel% / !errorlevel! format.

This way you can treat the errorlevel like any other variable.

if %errorlevel% equ N [command]

in a loop


Thus:

Code: [Select]setlocal enabledelayedexpansion
for %%I in (*.sql) do (
find /n /i "PROD" %%I >> PROD_Check\PROD_Check_Lines.txt
if !errorlevel! equ 0 (copy %%I PROD_Check)
echo 1 >> PROD_Check\i.txt
)
You do know that MS files/paths have reversed slashes ("\") ?




if !errorlevel! equ N [command]

Regarding format, these are all acceptable

if condition command

if condition (command)

if condition (
command1
command2
[...]
)

if condition (command1) else (command2)

if condition (
command1
command2
[...]
) else (
command3
command4
[...]
)

note that with else, the closing parenthesis of the first block, the keyword ELSE and the opening parenthesis of the second block must all be on the same line.

Incidentally you can use the && and || operators to test for errorlevel.

command1 && command2

command2 will execute (only) if command1 returned with an errorlevel of zero

command1 || command2

command2 will execute (only) if command1 returned with an errorlevel which is nonzero.


And you can do this

command1 && (
command2
command3
command4
)

etc


Discussion

No Comment Found