我已将有问题的代码删除到有问题的行。为什么第一个回声有效,第二回声不起作用?
setlocal enabledelayedexpansion
set /a r=19
set blocks=MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
for /L %%a in (-%r%,1,%r%) do (
set /a w2=r
:: This works
set line=!blocks:~0,%r%!
echo( !line!
::This does'nt work
set line=!blocks:~0,!w2!!
echo( !line!
)
exit /b
EDITED: 我一直在努力,这条线有效:
call set line=%%blocks:~0,!w2!%%
现在的问题是:有人可以向我解释为什么我必须使用电话?
答案 0 :(得分:1)
您应该直接使用r
变量和扩展百分比,只要该值不会在循环内发生变化。
set line=!blocks:~0,%r%!
或者为其他变量使用辅助循环。
for /F "tokens=*" %%H in ("!w2!") do (
set line=!blocks:~0,%%H!
)
答案 1 :(得分:1)
扩展变量的可能方法!延迟扩展!在this post中描述了可能在代码块内部发生变化的子串位置或长度的其他变量:
要在FOR / IF内部索引更改时获取子字符串的值,请将子字符串括在双百分比符号中,并在命令前加上call。例如:
call set line=%%blocks:~0,!w2!%%
此方法充分利用了call
命令允许重新扩展以双百分号括起来的变量的事实,如this question的第二个答案中所述:
BatchLineParser:
1)阶段:扩展%var%
...
6)阶段:如果命令是CALL,则再次从阶段1开始。
实现上一个过程的另一种方法是使用额外的FOR命令通过等效的可替换参数更改索引的延迟扩展,然后对子字符串使用延迟扩展。此方法比以前的CALL运行得更快:
for %%w in (!w2!) do set line=!blocks:~0,%%w!