Reputation: 97
Im trying to make a batch file that loops thru an array containing numbers like this: 1 2 3 4 5. In the first itteration of the loop I like to pick token 1 and 2. In the second 2 and 3, in the third 3 and 4 and so on.
I do think I should use ! in the variables first and second that I use as tokens. Like in the first FOR /F, but when I do, I get: !first!" was not expected here.
And if I use %, it does not count up. Everything works except the variable tokens. Any one knowes how to? Any help or suggestions greatly appriciated. This is the part Im struggeling with:
setlocal EnableDelayedExpansion
set first=1
set second=2
set N=4
set output="1 2 3 4 5"
set output=%output:"=%
for /L %%a in (1,1,%N%) do (
if !counter! equ active (
set /a first+=1
set /a second+=1
)
FOR /F "tokens=!first!" %%a IN ("%output%") DO (
set nr1=%%a
)
FOR /F "tokens=%second%" %%a IN ("%output%") DO (
set nr2=%%a
)
echo nr1 var: !nr1!
echo nr2 var: !nr2!
echo counter f: !first!
echo counter s: !second!
set counter=active
)
Upvotes: 3
Views: 626
Reputation: 34909
You cannot use delayed expanded variables in the options string of for /F
. Neither can you use other for
variables for that. But you can use normally (immediately) expanded variables. Also you can use argument references like %1
, for example.
So a nice work-around for your problem is to place the for /F
loop in a sub-routine and use call
in the main program with the delayed expanded variables as arguments, like this:
@echo off
setlocal EnableDelayedExpansion
set /A first=1
set /A second=2
set /A N=4
set "output=1 2 3 4 5"
set "counter="
for /L %%a in (1,1,%N%) do (
if defined counter (
set /A first+=1
set /A second+=1
)
call :SUB !first! !second!
echo nr1 var: !nr1!
echo nr2 var: !nr2!
echo counter f: !first!
echo counter s: !second!
set "counter=active"
)
endlocal
exit /B
:SUB val_token1 val_token2
for /F "tokens=%~1,%~2" %%a in ("%output%") do (
if %~1 LSS %~2 (
set "nr1=%%a"
set "nr2=%%b"
) else if %~1 GTR %~2 (
set "nr1=%%b"
set "nr2=%%a"
) else (
set "nr1=%%a"
set "nr2=%%a"
)
)
exit /B
Since you are extracting tokens from the same string, I combined your two for /F
loops into a single one. The if
block in the for /F
loop in the sub-routine :SUB
is there just in case the second token number is not always greater than the first one. But if that can guaranteed, the for /F
loop needs to contain only set "nr1=%%a"
and set "nr2=%%b"
.
Upvotes: 2