批量递归动态变量的返回值

时间:2011-10-05 21:31:56

标签: variables dynamic batch-file return

我试图在延迟变量扩展中使用动态变量来表示其他动态变量。我遇到了一些麻烦。如果动态变量的值是另一个具有自己值的动态变量,我怎样才能获得动态变量的值?

即。 !瓦拉! =%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

任何帮助都将不胜感激。

2 个答案:

答案 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?