如何两次扩展CMD shell变量(递归)

jon*_*son 12 windows shell scripting cmd batch-file

使用Windows XP CMD命令行,我可以将变量扩展两次,如下所示:

set AAA=BBB
set BBB=CCC
for /F "usebackq tokens=*" %i in (`echo %%AAA%%`) do echo %i
Run Code Online (Sandbox Code Playgroud)

会回应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!

)
Run Code Online (Sandbox Code Playgroud)

我想看看

111
222
333
Run Code Online (Sandbox Code Playgroud)

输出.

akf*_*akf 13

考虑到一个不那么曲折的解决方案,这也会产生CCC你的愿望.

setlocal enabledelayedexpansion
set AAA=BBB
set BBB=CCC
for /F  %%a in ('echo %AAA%') do  echo !%%a!
Run Code Online (Sandbox Code Playgroud)

编辑:

剖析这个答案:

setlocal enabledelayedexpansion- 这将允许您的蝙蝠期间的任何环境变量设置在for循环过程中被修改使用.

set AAA=BBB,set BBB=CCC- 您的数据填充set语句

for /F %%a in ('echo %AAA%') do echo !%%a! - 这告诉处理器循环,虽然只循环一次,并从parens中的命令运行中取出返回的第一个标记(空格和标签应用的默认分隔符)并将其放入var %% a(外部)批量,单个%会做).如果将var指定为%% a,则需要在do块中使用%% a .同样,如果指定%% i,请在do块中使用%% i .请注意,要使环境变量dofor循环块中得到解析,您需要将其包围在其中!.(你不需要在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!
)
Run Code Online (Sandbox Code Playgroud)

您的更新与此之间的区别在于您尝试在in集合中回显环境变量in ('echo %%%i%'),但没有!用于设置变量的延迟扩展的's.如果你使用in ('echo !%%i!'),你会看到你的BBB,, CCCDDD变量被解析,但是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!)
Run Code Online (Sandbox Code Playgroud)


Pio*_*ost 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
Run Code Online (Sandbox Code Playgroud)

输出:

Variable value before expansion: second
Variable value after expansion: fifth
Run Code Online (Sandbox Code Playgroud)


wqw*_*wqw 5

这个aaa.bat

@echo off
set aaa=bbb
set bbb=ccc
for /F %%i in ('echo %%%aaa%%%') do echo %%i
Run Code Online (Sandbox Code Playgroud)

产出

c:>ccc
Run Code Online (Sandbox Code Playgroud)

究竟是什么问题?