批量递归动态变量的返回值
我试图在延迟变量扩展中使用动态变量来表示其他动态变量。我遇到了一些麻烦。如果动态变量的值是另一个具有其自身值的动态变量,如何获取动态变量的值?
即!valA! = %valB% = this
@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
如有任何帮助,我们将不胜感激。
I'm attempting to use dynamic variables within Delayed Variable Expansion to represent other Dynamic Variables. I'm running into some trouble. How can I get a dynamic variable's value's value if the dynamic variable's value is another dynamic variable with it's own value?
i.e. !valA! = %valB% = this
@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
Any help would be appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
从逻辑上讲,您的失败代码等同于
正如之前的答案和评论中已经指出的那样,您无法为 VAR2 分配一个值,然后在同一代码块中使用 %VAR2% 访问该值,因为 %VAR2% 在解析过程中被扩展代码块的阶段,此时该值不是您想要的(可能未定义)。
但除了!VAR2! 之外,您还需要第二级扩展。得到你想要的结果。我知道三种解决方案。
1) 此解决方案可行,但不推荐,因为它很慢。
在执行 CALL 之前,每个 %% 都会减少为 %,并且 !VAR2!变为VAR1。
这样被调用的语句就变成了set VAR3=%VAR1%,并且被调用的语句通过%var%扩展阶段被重新解析,这样你就得到了你想要的结果。
但是 - CALL 相对非常昂贵。当在循环中使用时,可能会导致严重的性能下降。 jeb 在 打电话给我,或者更好地避免打电话
1a) CALL 解决方案有一种变体,您可以调用 :LABELed子程序。因为子例程是在调用后解析的,所以您可以简单地使用
set VAR3=!%VAR2%!
。但同样,这使用了 CALL,因此相对较慢,不推荐。2) 这个通用解决方案有效,并且相比之下速度快得多。它使用 FOR 变量进行第二级扩展。这是推荐的解决方案。
3) 如果已知 VAR1 的值是整数,则有一个使用
SET /A
的特殊情况解决方案SET /A 命令有其自己的内置扩展延迟扩展后发生的变量,不需要标点符号。
Logically your failing code equates to
As has already been pointed out in previous answers and comments, you can't assign a value to VAR2 and then access the value using %VAR2% within the same code block because %VAR2% is expanded during the parsing phase of the code block, at which point the value is not what you want (probably undefined).
But you need a second level of expansion in addition to !VAR2! to get the result you want. I know of three solutions.
1) This solution works, but it is not recommended because it is slow.
Prior to the execution of the CALL, each %% is reduced to %, and !VAR2! becomes VAR1.
Thus the called statement becomes
set VAR3=%VAR1%
, and the called statement is reparsed through the %var% expansion phase, so you get your desired result.BUT - CALL is relatively very expensive. When used in a loop it can cause severe performance degradation. jeb provides a good demonstration and explanation at CALL me, or better avoid call
1a) There is a variation of the CALL solution where you call a :LABELed subroutine. Because the subroutine is parsed after the call, you can simply use
set VAR3=!%VAR2%!
. But again, this uses CALL so it is relatively slow and not recommended.2) This general solution works, and is MUCH faster in comparison. It uses a FOR variable for the second level of expansion. This is the recommended solution.
3) If the value of VAR1 is known to be an integer, then there is a special case solution using
SET /A
The SET /A command has its own built in expansion of variables that takes place after delayed expansion, and no punctuation is needed.
您的代码在
SET _temp=!%_temp%!
处失败,因为在解析括号块时会评估百分比扩展。你可以把它改成顺便说
一句。如果您的示例可以减少到最少的代码,那么事情就会容易得多。
仅当它不在括号中时才有效。
为了更好地了解不同扩展的工作原理,
您可以阅读 Windows 命令如何解释器(CMD.EXE)解析脚本?
Your code fails at
SET _temp=!%_temp%!
, as the percent expansion is evaluated while parsing the parenthesis block.You could change it to
Btw. It would be much easier, if your sample would be reduced to the minimum of code, like.
This only works as it isn't in brackets.
To better understand how the different expansions work,
you can read How does the Windows Command Interpreter (CMD.EXE) parse scripts?