用于替换批处理文件中的延迟扩展变量

时间:2014-08-01 21:49:56

标签: arrays windows batch-file for-loop

我需要使用循环来替换已在Windows批处理文件中分配的变量中的变量(%% g)。我试过,只有当我使用%var%时它才有效,但如果我使用!var!它没有替换变量而且它是一个问题,因为我在数组中有这些变量,我只能使用!var [%% h]! (%var [%% h]%不起作用)。 有没有办法让它发挥作用?也许打电话给某事?

以下是一个例子:

setlocal EnableDelayedExpansion
SET var[0]=Hi %%g
SET var[1]=Ciao %%g
SET var[2]=Hola %%g
SET var[3]=Hallo %%g
SET var[4]=Salut %%g
FOR %%g in ( Luke Paul Tom Mark) DO (
    for /L %%h in (0,1,4) do (
    ECHO !var[%%h]!
    )
)

这是我得到的:

Hi %g
Ciao %g
Hola %g
Hallo %g
Salut %g
Hi %g
Ciao %g
Hola %g
Hallo %g
Salut %g
Hi %g
Ciao %g
Hola %g
Hallo %g
Salut %g
Hi %g
Ciao %g
Hola %g
Hallo %g
Salut %g

以下是我想要的内容:

Hi Luke
Ciao Luke
Hola Luke
Hallo Luke
Salut Luke
Hi Paul
Ciao Paul
Hola Paul
Hallo Paul
Salut Paul
Hi Tom
Ciao Tom
Hola Tom
Hallo Tom
Salut Tom
Hi Mark
Ciao Mark
Hola Mark
Hallo Mark
Salut Mark

2 个答案:

答案 0 :(得分:1)

@echo off
setlocal EnableDelayedExpansion
SET var[0]=Hi %%%%g
SET var[1]=Ciao %%%%g
SET var[2]=Hola %%%%g
SET var[3]=Hallo %%%%g
SET var[4]=Salut %%%%g
FOR %%g in ( Luke Paul Tom Mark) DO (
    for /L %%h in (0,1,4) do (
    call :myECHO !var[%%h]!
    )
)
goto :EOF

:myECHO
for %%x in (1) do echo %*
exit /B

编辑添加了一些解释

您的原始程序在输出中显示%g,因为FOR命令中元素的解析顺序:

  • 1-第一个FOR可替换参数的扩展,从%%gLukePaul等。
  • 2-第二个FOR可替换参数的扩展,从%%h扩展到0 1 2 3 4
  • 3- !var[0]!!var[1]!等按其值扩展:Hi %gCiao %g

目前,%g的扩展已经完成了两个步骤,因此不再再次执行。您可以在this post查看有关此扩展订单的更详细说明。

我们需要再次解析数组元素的最终值,以便将%g更改为当前值,最简单的方法是调用子例程。但是,当在子例程中解析每个数组元素的值时,会发生百分号的常规处理,因此数组元素的原始值必须是百分号的两倍。

我们可以在参数中将%%g的当前值传递给子例程,并在最终值中明确替换它,例如:

    call :myECHO "%%g" "!var[%%h]!"
    . . .
    . . .
:myECHO
set "var=%~2"
echo !var:%%g=%~1!
exit /B

但是,我选择了一个有趣的技巧,可以通过这种方式进行总结:所有活动 FOR命令的可替换参数将替换为{{}内执行的代码中的值。 1}}命令即使这样的代码放在一个单独的子程序中也是如此。这样,为了能够访问子例程中的原始FOR可替换参数,只需要激活%%g命令。这一点在this post进一步解释。

答案 1 :(得分:0)

测试一下:

@echo off
setlocal enabledelayedexpansion
FOR %%g in (Luke Paul Tom Mark) DO (
SET var[0]=Hi %%g
SET var[1]=Ciao %%g
SET var[2]=Hola %%g
SET var[3]=Hallo %%g
SET var[4]=Salut %%g
    for /L %%h in (0,1,4) do (
    ECHO !var[%%h]!
    )
pause
)