使用Windows XP CMD命令行,我可以将变量扩展两次,如下所示:
set AAA=BBB
set BBB=CCC
for /F "usebackq tokens=*" %i in (`echo %%AAA%%`) do echo %i
将回显CCC
。即AAA
已扩展为字符串BBB
,然后变量BBB
已扩展为CCC
。
这不适用于批处理脚本(即.cmd文件)内部。将%%AAA%%
更改为%%%AAA%%%
或%%%%AAA%%%%
也不起作用。
知道如何从脚本中实现这一点,即将变量AAA扩展为字符串CCC?
延迟修改
这些答案发布了我的缩减示例,但非曲折的答案对真实案例不起作用。这是一个扩展示例(不起作用),它说明了我实际上要做的事情:
setlocal enabledelayedexpansion
set LIST=BBB CCC DDD
set BBB=111
set CCC=222
set DDD=333
for %%i in (%LIST%) do (
for /F %%a in ('echo %%%i%') do echo !%%a!
)
我想看看
111
222
333
输出
答案 0 :(得分:13)
从一个不那么曲折的解决方案的角度思考,这也会产生你想要的CCC
。
setlocal enabledelayedexpansion
set AAA=BBB
set BBB=CCC
for /F %%a in ('echo %AAA%') do echo !%%a!
修改强>
剖析这个答案:
setlocal enabledelayedexpansion
- 这将允许您的球棒中的任何环境变量设置在for
循环过程中被修改使用。
set AAA=BBB
,set BBB=CCC
- 您的数据填充set
语句
for /F %%a in ('echo %AAA%') do echo !%%a!
- 这告诉处理器循环,虽然只循环一次,并从parens中的命令运行中取出返回的第一个标记(空格的默认分隔符和tab应用)并将其放入在var %% a中(在批处理之外,单个%会这样做)。如果将var指定为%% a,则需要在do
块中使用%% a。同样,如果您指定%% i,请在do
块中使用%% i。请注意,要使您的环境变量在do
循环的for
块中得到解析,您需要将其包围在!
中。 (你不需要在in
块中,就像我最初发布的那样 - 我在编辑中做了这个改变)。
修改强>
您与最新的示例非常接近。试试这样:
@echo off
setlocal enabledelayedexpansion
set LIST=BBB CCC DDD
set BBB=111
set CCC=222
set DDD=333
for %%i in (%LIST%) do (
for /F %%a in ('echo %%i') do echo !%%a!
)
您的更新与此之间的区别在于您尝试使用in
来回显in ('echo %%%i%')
集合中的环境变量,但没有!
用于延迟扩展设置变量。如果您使用in ('echo !%%i!')
,您会看到已解析BBB
,CCC
和DDD
个变量,但内循环的do
块不会要解决的任何事情 - 你没有任何111
环境变量。考虑到这一点,您可以使用以下内容简化循环:
@echo off
setlocal enabledelayedexpansion
set LIST=BBB CCC DDD
set BBB=111
set CCC=222
set DDD=333
for %%i in (%LIST%) do (echo !%%i!)
答案 1 :(得分:8)
如何多次展开shell变量:
@echo off
setlocal enabledelayedexpansion
set myvar=second
set second=third
set third=fourth
set fourth=fifth
echo Variable value before expansion: !myvar!
call :expand myvar
echo Variable value after expansion: !myvar!
goto :eof
:expand
set var=%1
:expand_loop
if not "!%var%!" == "" (
set var=!%var%!
goto :expand_loop
)
set %1=!var!
goto :eof
输出:
Variable value before expansion: second
Variable value after expansion: fifth
答案 2 :(得分:3)
以下(曲折)方法似乎没有问题:
@echo off
:main
setlocal enableextensions enabledelayedexpansion
set aaa=bbb
set bbb=ccc
call :myset x %%aaa%%
echo %x%
endlocal
goto :eof
:myset
for /F "usebackq tokens=*" %%i in (`echo %%%2%%`) do set %1=%%i
goto :eof
输出:
ccc
根据需要。
我经常使用这个技巧(例如)将%aaa%
格式化为%x%
到一定的大小(la sprintf
)但这是我第一次拥有做双重间接。它的工作原理是因为您没有找到当前shell级别所吸引的额外"%%"
。
答案 3 :(得分:3)
这是aaa.bat
@echo off
set aaa=bbb
set bbb=ccc
for /F %%i in ('echo %%%aaa%%%') do echo %%i
输出
c:>ccc
究竟是什么问题?
答案 4 :(得分:1)
OP问题几乎适用于Windows 10.需要进行小的修正才能正确形成ECHO
命令。这是中间结果:
set LIST=BBB CCC DDD
set BBB=111
set CCC=222
set DDD=333
for %%i in (%LIST%) do echo %%%%i%%
rem // Outputs:
rem // %AAA%
rem // %BBB%
rem // %CCC%
然后我们将输出嵌套在另一个FOR
语句中并获得完整的结果:
set LIST=BBB CCC DDD
set BBB=111
set CCC=222
set DDD=333
for %%i in (%LIST%) do for /f %%a in ('echo %%%%i%%') do echo %%a
rem // Outputs:
rem // 111
rem // 222
rem // 333
答案 5 :(得分:0)
双重间接(这是一种非常恰当的方式pax
已经把它)提醒C指针解除引用。
我怀疑Windows command shell是否支持。
您是否认为您所针对的更大目标可以通过更简单的方式实现;
也许较少的代码 - 高尔夫方法然后pax
很好地设计了一个?
答案 6 :(得分:0)
似乎最简单的事情就是创建一个微小的临时文件来根据需要设置变量。这样的事情应该有效:
setlocal enabledelayedexpansion
set LIST=BBB CCC DDD
set BBB=111
set CCC=222
set DDD=333
for %%i in (%LIST%) do (
echo set a=\%%%i\%>tmp.bat
call tmp.bat
echo %a
rm tmp.bat
)