Возвращаемые значения рекурсивных динамических переменных в пакете - PullRequest
1 голос
/ 06 октября 2011

Я пытаюсь использовать динамические переменные в расширении отложенных переменных для представления других динамических переменных.У меня проблемы.Как я могу получить значение динамической переменной, если значение динамической переменной является другой динамической переменной со своим собственным значением?

то есть! 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

Любая помощь будет оценена.

Ответы [ 2 ]

1 голос
/ 31 октября 2011

Логически ваш ошибочный код равен

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%, поэтому вы получаете желаемый результат.

НО - ЗВОНОК относительно дорог. При использовании в цикле это может привести к серьезному снижению производительности. Джеб дает хорошую демонстрацию и объяснение на Позвоните мне, или лучше избегайте звонить

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 имеет собственное встроенное раскрытие переменных, которое происходит после отложенного раскрытия, и пунктуация не требуется.

0 голосов
/ 06 октября 2011

Ваш код завершается с ошибкой на SET _temp=!%_temp%!, так как процентное расширение оценивается при разборе блока скобок.

Вы можете изменить его на

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

Кстати.Было бы намного проще, если бы ваш пример был сокращен до минимума кода, например.

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

Это работает только так, как в скобках.

Чтобы лучше понять, какразличные расширения работают,
вы можете прочитать Как интерпретатор сценариев команд Windows (CMD.EXE) анализирует?

...