【问题标题】:Return Values of Recursive Dynamic Variables in Batch递归动态变量批量返回值
【发布时间】:2011-10-05 21:31:55
【问题描述】:

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

即!valA! = %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

任何帮助将不胜感激。

【问题讨论】:

  • 哇!博士级批处理脚本。我认为这些天每个人都明智并使用了 PowerShell
  • 我很好奇这行:“SET _temp=!%_temp%!”。你能解释一下你想做什么吗?
  • @Arun 将 _temp 重新分配给当前的 _temp(变量名)值。

标签: variables dynamic batch-file return


【解决方案1】:

逻辑上你的失败代码等同于

setlocal enableDelayedExpansion
(
  set VAR1=success
  set VAR2=VAR1
  set VAR3=!%VAR2%!
  echo VAR3=!VAR3!
)

正如在之前的答案和 cmets 中已经指出的那样,您不能为 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) 这个通用的解决方案很有效,并且相比起来要快得多。它使用 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 命令有自己的内置变量扩展,在延迟扩展之后发生,不需要标点符号。

【讨论】:

  • 我最终以另一种方式解决了它,但我忘记了它是什么,因为我辞去了那份工作。
  • 我想我在重读这篇文章后撒了谎。我不确定,但我认为我选择了与您的#2 @dbenham 类似的东西。我记得我花了几天时间仔细考虑并让它发挥作用。我将尝试获取一些旧脚本,这样我就可以看到我实际上做了什么。感谢您很久以前的帮助。 :)
【解决方案2】:

您的代码在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?

【讨论】:

  • 代码块是从一个较大的代码块中解析出来的,在调用其他函数时与其他代码块不能很好地配合。这就是生活。干杯。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-08
  • 1970-01-01
  • 2016-02-02
  • 1970-01-01
  • 1970-01-01
  • 2014-07-14
相关资源
最近更新 更多