BAT文件:变量内容作为另一个变量的一部分

时间:2012-03-14 10:35:44

标签: variables batch-file

假设我有变量 a ,内容为“ 123 ”,变量 b123 ,其中包含一些文字。出于某种原因,我想使用变量 a 作为第二个var名称的一部分。像这样:

SET a=123
SET b123=some_text_in_it
rem i want next line to output  "some_text_in_it"
echo %b%a%%

所以我想将文本与var内容连接起来,并使用结果字符串作为变量名称来回显该内容。上面的示例不起作用,我明白为什么,可能我需要添加一些灌浆。怎么做,最好在一条线上?

3 个答案:

答案 0 :(得分:8)

这有两种常见的方法 CALLDelayedExpansion

setlocal EnableDelayedExpansion
SET a=123
SET b123=some_text_in_it
rem i want next line to output  "some_text_in_it"
call echo %%b%a%%%
echo !b%a%!

CALL变体使用的事实是,调用会再次重新分析该行,第一次只展开%a%并将双%%缩减为单%
call echo %b123%
在第二步中,%b123%将被扩展 但是CALL技术很慢而且不太安全,所以应该首选DelayedExpansion。

DelayedExpansion的工作原理是感叹号在后来的解析器阶段扩展而不是百分比的扩展。
这也是原因,为什么延迟扩张会更加安全。

编辑:包含数字的数组的方法
如果您使用的数组只包含数字,您也可以使用set /a来访问它们 这比FORCALL技术要容易得多,而且它也可以在块中使用。

setlocal EnableDelayedExpansion
set arr[1]=17
set arr[2]=35
set arr[3]=77
(
  set idx=2
  set /a val=arr[!idx!]
  echo !var!
)

答案 1 :(得分:2)

“将变量用作第二个var名称的一部分”的最佳理由是通过下标变量访问数组(向量和矩阵)元素。虽然这与上面的示例完全相同,但它看起来更清晰:

setlocal EnableDelayedExpansion
set i=123
set v[123]=Value of element 123
call echo %%v[%i%]%%
echo !v[%i%]!

尽管CALLDelayed Expansion慢,但正如上面所说的jeb,它可能会嵌套几次,允许使用第二个(或更深的)间接访问数组元素。此功能可用于复杂的数据结构,如链接列表。例如:

set i=123
set v[123]=456
set w[456]=Value of element 456
call call echo %%%%w[%%v[%i%]%%]%%%%

编辑:由于某些原因我不明白,最后一个命令的延迟扩展版本无法正常运行:

call echo !w[%%v[%i%]%%]!

答案 2 :(得分:2)

还有一种方法可以完成任务,如果在扩展它们的同一个带括号的块中分配了两个变量,那么这个方法非常有用。该解决方案类似于jeb的延迟扩展答案,除了它使用FOR变量而不是正常扩展。

@echo off
setlocal enableDelayedExpansion

:: Define a linefeed value - only needed for last variant
set LF=^


:: The two blank lines above are critical to the definition of LF

(
  set A=123
  set B123=some_text_in_it

  rem ECHO !B%A%! will fail because A was assigned within the same block

  rem This works as long as A does not contain * or ?
  for %%A in ("!A!") do echo !B%%~A!

  rem This works as long as A does not start with EOL character (; by default)
  for /f "delims=" %%A in ("!A!") do echo !B%%A!

  rem This will never fail because it disables EOL by setting it to a linefeed
  for /f eol^=^%LF%%LF%^ delims^= %%A in ("!A!") do echo !B%%A!
)

也可以使用CALL技巧,但相对来说它很慢,而且不可靠 - 请参阅CALL me, or better avoid call

Explain how dos-batch newline variable hack works讨论了换行变量的定义和使用。

HOW TO: FOR /F Disabling EOL or using a quote as delim详细描述了将EOL设置为换行符。使用LF变量而不是在FOR语句中嵌入换行只是该技术的扩展。它使代码更具可读性。

<强> 修改
将FOR技术安全地用于任何有效值的一种更简单的方法是将EOL设置为等号,因为没有用户定义的变量可以在名称中包含=。

for /f "eol== delims=" %%A in ("!A!") do echo !B%%A!