Reputation: 65
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
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:
setlocal enabledelayedexpansion
and use !var!
in place of %var%
to access the changed value of var
, or 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
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
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