user1838817
user1838817

Reputation: 65

Multiple commands and variables in a batch file loop

I looked through all of the previously asked similar questions but couldn't find the answer.

I have a batch file that creates new batch files with specific text inside them, the text is taken from a specific directory. It works great, but right now a lot of code is repeated multiple times, and should be automated.

Here is the working code that I have:

set /p x=<"path were all the source files are kept\FileOne.txt"
set x=%x:~20%
set y="C:\Program Files\TightVNC\tvnviewer" -password=zzz %x%
break> FileOne.bat
echo %y% >>FileOne.bat

First line opens a specific directory, opens a text file and saves the first line of it as x.

The second then removes the first 20 symbols from it, leaving only the needed part.

The third line sets Y to the command I need inside the newly created batch file and puts X at the end of it.

Then Y is saved as an output .bat file.

This code is repeated again and again for FileTwo, FileThree, FIleFour and so on.

Here is how I tried to turn it into a loop:

etlocal enabledelayedexpansion

FOR %%A in (FileOne FileTwo) DO (

set /p x=<"path were all the source files are kept\%%A.txt"
set x=%x:~20%
set y="C:\Program Files\TightVNC\tvnviewer" -password=zzz %x%
break> %%A.bat
echo %y% >>%%A.bat

)

The two files are created as planned, but both of them had Echo is Off inside (or, when I turned it on, Echo is On).

Here is the console output:

C:\>setlocal enabledelayedexpansion

C:\>FOR %A in (FileOne FileTwo) DO (
set /p x= 0<"path were all the source files are kept\%A.txt"
 set x=~20
 set y="C:\Program Files\TightVNC\tvnviewer" -password=zzz %x%
 break1>%A.bat
 echo   1>>%A.bat
)

C:\>(
set /p x= 0<"path were all the source files are kept\FileOne.txt"
 set x=~20
 set y="C:\Program Files\TightVNC\tvnviewer" -password=zzz %x%
 break1>FileOne.bat
 echo   1>>FileOne.bat
)

C:\>(
set /p x= 0<"path were all the source files are kept\FileTwo.txt"
 set x=~20
 set y="C:\Program Files\TightVNC\tvnviewer" -password=zzz %x%
 break1>FileTwo.bat
 echo   1>>FileTwo.bat
)

I see that it did make the loop, and created the files, but some commands look corrupt for some reason. Is there a special way I need to declare and use other variables inside a loop in a .bat file?

Upvotes: 0

Views: 4705

Answers (3)

Magoo
Magoo

Reputation: 80013

Within a block statement (a parenthesised series of statements), the entire block is parsed and then executed. Any %var% within the block will be replaced by that variable's value at the time the block is parsed - before the block is executed - the same thing applies to a FOR ... DO (block).

Hence, IF (something) else (somethingelse) will be executed using the values of %variables% at the time the IF is encountered.

In your case, y and x are each being set within the loop, so their values when the loop was parsed are used. In all probability, these values were empty so for instance echo %y% would be interpreted as echo and hence the current echo state would be reported.

Two common ways to overcome this are:

  1. Use setlocal enabledelayedexpansion and use !var! in place of %var% to access the changed value of var, or
  2. Call a subroutine to perform further processing using the changed values.

So, to solve, add a line setlocal enabledelayedexpansion after the @echo off line and then replace any %x% or %y% within your loop with !x! or !y!

(see endless articles on SO about delayedexpansion)

BTW - why are you removing the firrst 20 characters of x? Wouldn't it be easier simply not to type them in?

Upvotes: 4

cypizek
cypizek

Reputation: 337

You can run batch in CMD with enabled delayed environment variable expansion.

CMD /V:ON

And without setlocal enabledelayedexpansion command in file. And echo %y% >>%%A.bat must be changed to (echo %y%) >>%%A.bat to strip quotes out.

Upvotes: 0

SomethingDark
SomethingDark

Reputation: 14305

When you define a variable inside of a for loop, you need to use delayed expansion. Having the setlocal enabledelayedexpansion command is not enough; you also need to change % to !

FOR %%A in (FileOne FileTwo) DO (

set /p x=<"path were all the source files are kept\%%A.txt"
set x=!x:~20!
set y="C:\Program Files\TightVNC\tvnviewer" -password=zzz !x!
break> %%A.bat
echo !y! >>%%A.bat

)

Upvotes: 1

Related Questions