使用Windows XP CMD命令行我可以扩展一个variables两次,如下所示:
set AAA=BBB set BBB=CCC for /F "usebackq tokens=*" %i in (`echo %%AAA%%`) do echo %i
会回应CCC
。 即AAA
已扩展到stringBBB
,然后variablesBBB
已扩展到CCC
。
这从批处理脚本(即.cmd文件)不起作用。 将%%AAA%%
更改为%%%AAA%%%
或%%%%AAA%%%%
也不起作用。
任何想法如何我可以从一个脚本内实现这一点,即将可变AAA扩展到stringCCC?
晚编辑
答案张贴工作为我的简单例子,但非曲折的答案不起作用的真实情况。 这是一个扩展的例子(不起作用),它说明了我实际上正在做的事情:
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
输出。
思考一个不太曲折的解决方案,这也产生了你想要的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
– 您的数据填充语句
for /F %%a in ('echo %AAA%') do echo !%%a!
– 这告诉处理器循环,尽管只有一次,并从parens中的命令运行中取出返回的第一个标记(空格和制表符的默认分隔符),并将其放入var %% a(outside的一批,一个%将做)。 如果你将var指定为%% a,则需要在do
块中使用%% a。 同样,如果您指定%% i,则在do
块中使用%% i。 请注意,为了让您的环境变量在for
循环的do
块中得到解决,您需要将它包围在内!
的。 (你不需要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
设置环境变量,但没有!
对于设定变量的延迟扩展。 如果你in ('echo !%%i!')
,你会看到你的BBB
, CCC
和DDD
变量已经解决了,但是你的内部循环的do
块没有任何解决方法 – 你没有任何的环境变量。 考虑到这一点,你可以简化你的循环与以下几点:
@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!)
如何多次展开一个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
以下(折磨)的方法似乎工作正常:
@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%
,达到一定的大小(一个sprintf
),但是这是我第一次不得不做双重间接。 这是因为你没有发现额外的"%%"
被当前的shell级别所吸引。
这个aaa.bat
@echo off set aaa=bbb set bbb=ccc for /F %%i in ('echo %%%aaa%%%') do echo %%i
输出
c:>ccc
究竟是什么麻烦?
这是一个有点过时的问题,但有趣的是,答案现在更简单了。 我在Windows 10上运行这些脚本:
setlocal enabledelayedexpansion set AAA=BBB set BBB=CCC echo !%AAA%!
输出
CCC
对于扩展版本,这可以工作:
setlocal enabledelayedexpansion set LIST=BBB CCC DDD set BBB=111 set CCC=222 set DDD=333 for %%i in (%LIST%) do ( echo !%%i! )
输出
111 222 333
双重间接(这是一个非常合适的方式pax
已经把它)提醒C指针取消参考。
我怀疑Windows命令外壳是否受支持。
你认为你所瞄准的更大的目标可以通过更简单的方式来实现。
也许更少的代码高尔夫的方法,那么由pax
很好地作出的?
看起来最简单的做法是创建一个小的临时文件来设置变量,如你所愿。 像这样的东西应该工作:
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 )