变量作为 for 循环中的标记
variable as tokens in for loop
我正在尝试制作一个批处理文件,循环遍历包含如下数字的数组:1 2 3 4 5。
在循环的第一次迭代中,我喜欢选择标记 1 和 2。在第二个 2 和 3,在第三个 3 和 4,依此类推。
我认为我应该使用!在我用作标记的变量 first 和 second 中。就像在第一个 FOR /F 中一样,但是当我这样做时,我得到:!first!" 在这里不是预期的。
如果我用%,它就不算了。
除了变量标记外,一切正常。有人知道怎么做吗?非常感谢任何帮助或建议。
这是我苦苦挣扎的部分:
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
)
您不能在for /F
的选项字符串中使用延迟扩展变量。您也不能为此使用其他 for
变量。但是您可以使用通常(立即)扩展的变量。您也可以使用参数引用,例如 %1
。
因此,解决您的问题的一个很好的解决方法是将 for /F
循环放在子例程中,并在主程序中使用 call
并将延迟的扩展变量作为参数,如下所示:
@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
由于您是从同一个字符串中提取标记,我将您的两个 for /F
循环合并为一个循环。子例程 :SUB
中 for /F
循环中的 if
块在那里,以防第二个标记号并不总是大于第一个。但如果可以保证,for /F
循环只需要包含 set "nr1=%%a"
和 set "nr2=%%b"
.
我正在尝试制作一个批处理文件,循环遍历包含如下数字的数组:1 2 3 4 5。 在循环的第一次迭代中,我喜欢选择标记 1 和 2。在第二个 2 和 3,在第三个 3 和 4,依此类推。
我认为我应该使用!在我用作标记的变量 first 和 second 中。就像在第一个 FOR /F 中一样,但是当我这样做时,我得到:!first!" 在这里不是预期的。
如果我用%,它就不算了。 除了变量标记外,一切正常。有人知道怎么做吗?非常感谢任何帮助或建议。 这是我苦苦挣扎的部分:
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
)
您不能在for /F
的选项字符串中使用延迟扩展变量。您也不能为此使用其他 for
变量。但是您可以使用通常(立即)扩展的变量。您也可以使用参数引用,例如 %1
。
因此,解决您的问题的一个很好的解决方法是将 for /F
循环放在子例程中,并在主程序中使用 call
并将延迟的扩展变量作为参数,如下所示:
@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
由于您是从同一个字符串中提取标记,我将您的两个 for /F
循环合并为一个循环。子例程 :SUB
中 for /F
循环中的 if
块在那里,以防第二个标记号并不总是大于第一个。但如果可以保证,for /F
循环只需要包含 set "nr1=%%a"
和 set "nr2=%%b"
.