我试图在延迟变量扩展中使用动态变量来表示其他动态变量。我遇到了一些麻烦。如果动态变量的值是另一个具有自己值的动态变量,我怎样才能获得动态变量的值?
即。 !瓦拉! =%valB%=此
@ECHO OFF
SETLOCAL EnableExtensions EnableDelayedExpansion
...
...
FOR /F ... %%G IN (...) DO (
SET _temp=%%~nG
SET _file=!_temp:~0,-4!
SET _cnt=0
FOR /F ... %%L IN (...) DO (
SET _temp=%%L
SET _str=!_temp:*: =!
SET /A _cnt+=1
SET _temp=x!_file!!_cnt!
IF DEFINED !_temp! (
SET _temp=!%_temp%!
::
::_temp('s value) is _var('s value) is "xyz"
::Set new _temp to equal current _temp's "xyz"
::
IF !_temp! NEQ !_str! (
ECHO File Content Mismatch
)
) ELSE (
SET xvar=!_temp!
SET !xvar!=!_str!
)
)
)
...
...
exit
任何帮助都将不胜感激。
答案 0 :(得分:1)
逻辑上,您的失败代码等同于
setlocal enableDelayedExpansion
(
set VAR1=success
set VAR2=VAR1
set VAR3=!%VAR2%!
echo VAR3=!VAR3!
)
正如之前的答案和评论中已经指出的那样,您无法为VAR2分配值,然后在同一代码块中使用%VAR2%访问该值,因为%VAR2%在解析阶段期间被扩展。代码块,此时该值不是您想要的值(可能是未定义的)。
但除了!VAR2之外,还需要第二级扩展!得到你想要的结果。我知道三种解决方案。
1)此解决方案有效,但建议不要这样做,因为它很慢。
setlocal enableDelayedExpansion
(
set VAR1=success
set VAR2=VAR1
call set VAR3=%%!VAR2!%%
echo VAR3=!VAR3!
)
在执行CALL之前,每个%%都减少到%,并且!VAR2!成为VAR1。
因此,被调用的语句变为set VAR3=%VAR1%
,并且通过%var%扩展阶段重新调用被调用的语句,因此您可以获得所需的结果。
但是 - CALL相对非常昂贵。在循环中使用时,可能会导致严重的性能下降。 jeb在CALL me, or better avoid call
提供了很好的演示和解释 1a) CALL解决方案有一种变体,您可以在其中调用:LABELed子例程。因为在调用之后解析子例程,所以您只需使用set VAR3=!%VAR2%!
。但同样,这使用了CALL,所以它相对较慢,不推荐使用。
2)这种通用解决方案有效,相比之下 MUCH 更快。它使用FOR变量进行第二级扩展。这是推荐的解决方案。
setlocal enableDelayedExpansion
(
set VAR1=success
set VAR2=VAR1
for /f %%A in ("!VAR2!") do set VAR3=!%%A!
echo VAR3=!VAR3!
)
3)如果已知VAR1的值为整数,则使用SET /A
setlocal enableDelayedExpansion
(
set VAR1=999
set VAR2=VAR1
set /a VAR3=!VAR2!
echo VAR3=!VAR3!
)
SET / A命令有自己内置的变量扩展,这些变量在延迟扩展后发生,不需要标点符号。
答案 1 :(得分:0)
您的代码在SET _temp=!%_temp%!
处失败,因为在解析括号块时会评估百分比扩展。
您可以将其更改为
set "varname=!_temp!"
set "content=!varname!"
顺便说一下。如果您的样本将减少到最小代码,那将会容易得多,例如。
setlocal EnableDelayedExpansion
set "var1=content of var1"
set "var2=var1"
set "result=!%var2%!"
echo !result!
这只适用,因为它不在括号内。
为了更好地理解不同的扩展如何工作,
你可以阅读How does the Windows Command Interpreter (CMD.EXE) parse scripts?