在循环中为endlocal分配变量

时间:2015-02-23 19:56:20

标签: batch-file

如何在循环中保留过去endlocal的多个变量(带有特定前缀)?

变量在循环声明中可见,但不在body中。

以下是使用echo代替变量赋值的示例,以说明变量在for正文中不可见。通常,变量赋值将代替echo

@echo off

setlocal ENABLEDELAYEDEXPANSION
set TB_1=test1
set TB_2=test2

set TB_ALL_VARS=
for /F "tokens=1 delims==" %%x in ('set TB_') do (
  set TB_ALL_VARS=%%x !TB_ALL_VARS!
)

for %%x in (%TB_ALL_VARS%) do ( echo %%x = !%%x! ) 
echo END LOCAL
endlocal & ( for %%x in (%TB_ALL_VARS%) do ( echo %%x = !%%x! ) )

输出:

TB_2 = test2
TB_1 = test1
END LOCAL
TB_2 = !TB_2!
TB_1 = !TB_1!

如您所见,变量在endlocal之前打印好,但在endlocal之后不打印。

有没有办法保存像过去的endlocal这样的变量?

2 个答案:

答案 0 :(得分:4)

鉴于您的示例代码,我认为您要问的是,"如何在endlocal之后设置动态数量的变量?"你问的不是非常直观,但 是可能的。将setendlocal复合时,您无法使用延迟展开。通常可以使用变通方法将for循环用于endlocal & set "var=%%A",这仅在变量和值的数量是静态时才有效。不幸的是,endlocal & forfor... in... do ( endlocal & set )的工作方式不同,因为您无疑会在自己的测试中发现。

我的解决方案是使用宏在endlocal之后进行设置 - 基本上将命令而不是简单的字符串值放入变量中,然后将该变量作为一组{进行评估{1}}命令。

set

另一个解决方案是回到我提到的第一个解决方法,格式为@echo off setlocal :: // call ":set" subroutine to do the setting call :set :: // display results set subv :: // end main runtime goto :EOF :: // :set subroutine :set setlocal enabledelayedexpansion :: // any number of variables prefixed by "subv" set "subv1=1" set "subv2=2" set "subv3=3" :: // init %compound% set compound= :: // combine all %subvX% variables into a macro of set var1=val1 & set var2=val2, etc for /f "delims=" %%I in ('set subv') do set "compound=!compound! & set "%%~I"" :: // evaluate set commands as a macro endlocal & %compound:~3% goto :EOF 。通常情况下,只有当您知道自己只循环一次时才会使用此功能,例如

endlocal & set "var=%%A"

...因为你不想太多次地方。但是你可以通过for %%I in ("!var!") do endlocal & set "return=%%~I" 这样使用endlocal进行多值循环:

if not defined

...因为@echo off setlocal call :set set subv goto :EOF :set setlocal enabledelayedexpansion set "subv1=1" set "subv2=2" set "subv3=3" set end= for /f "delims=" %%I in ('set subv') do ( if not defined end endlocal & set end=1 set "%%~I" ) goto :EOF endlocal包含在括号内的代码块中,所以变量会重新设置并实现目标。

答案 1 :(得分:3)

您尝试使用tunneling,但在endlocal之后,您无法使用!扩展变量。请尝试:

@echo off

setlocal ENABLEDELAYEDEXPANSION
set TB_1=test1
set TB_2=test2

set TB_ALL_VARS=
for /F "tokens=1 delims==" %%x in ('set TB_') do (
  set TB_ALL_VARS=%%x !TB_ALL_VARS!
)

for %%x in (%TB_ALL_VARS%) do ( echo %%x = !%%x! ) 
echo END LOCAL
endlocal & ( for %%x in (%TB_ALL_VARS%) do ( call echo %%x = %%%%x%% ) )

OR

@echo off

setlocal ENABLEDELAYEDEXPANSION
set TB_1=test1
set TB_2=test2

set TB_ALL_VARS=
for /F "tokens=1 delims==" %%x in ('set TB_') do (
  set TB_ALL_VARS=%%x !TB_ALL_VARS!
)

for %%x in (%TB_ALL_VARS%) do ( echo %%x = !%%x! ) 
echo END LOCAL
endlocal & ( for %%x in (%TB_ALL_VARS%) do (
 setlocal enableDelayedExpansion
 call echo %%x = !%%x! )
 endlocal 
 )