开发者

Return Values of Recursive Dynamic Variables in Batch

开发者 https://www.devze.com 2023-04-11 05:29 出处:网络
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 t

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.


Logically your failing code equates to

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

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.

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

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.

setlocal enableDelayedExpansion
(
  set VAR1=success
  set VAR2=VAR1
  for /f %%A in ("!VAR2!") do set VAR3=!%%A!
  echo VAR3=!VAR3!
)

3) If the value of VAR1 is known to be an integer, then there is a special case solution using SET /A

setlocal enableDelayedExpansion
(
  set VAR1=999
  set VAR2=VAR1
  set /a VAR3=!VAR2!
  echo VAR3=!VAR3!
)

The SET /A command has its own built in expansion of variables that takes place after delayed expansion, and no punctuation is needed.


Your code fails at SET _temp=!%_temp%!, as the percent expansion is evaluated while parsing the parenthesis block.

You could change it to

set "varname=!_temp!"
set "content=!varname!"

Btw. It would be much easier, if your sample would be reduced to the minimum of code, like.

setlocal EnableDelayedExpansion
set "var1=content of var1"
set "var2=var1"
set "result=!%var2%!"
echo !result!

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?

0

精彩评论

暂无评论...
验证码 换一张
取 消