【问题标题】:Batch: variable indirection: getting the value of a variable by dynamically constructed name批处理:变量间接:通过动态构造的名称获取变量的值
【发布时间】:2016-12-18 22:16:20
【问题描述】:

所以当我运行这段代码时:

@echo off
setlocal enabledelayedexpansion

set lstFolders= First Second 

set intCounter=0
for %%i in (!lstFolders!) do (
    set /a intCounter += 1
    set strFlder=%%i
    set strFolder!intCounter!=!strFlder!
    echo %%i
    echo !strFlder!
    echo !strFolder%intCounter%!
    echo !strFolder1!
    echo !strFolder2!
)

:End
pause
endlocal

结果如下:

First
First
ECHO is off.
First
ECHO is off.
Second
Second
ECHO is off.
First
Second

为什么它不允许我使用以下格式回显变量创建:!strFolder%intCounter%!?还有其他方法可以引用这个变量并获取其中的数据吗?

【问题讨论】:

  • 虽然不是完全重复,因为 this 问题还间接询问 creating 变量(并专注于使用延迟评估),以下问题密切相关:stackoverflow.com/q/9369874/45375

标签: variables batch-file echo indirection


【解决方案1】:

正如@mklement0 所说,您需要一个额外的评估步骤。
但是尽管使用echo "%%strFolder!intCounter!%%",我还是建议延迟扩展。
由于延迟扩展不受任何内容的影响,echo "%%strFolder... 会因包含引号或感叹号的内容而失败。

@echo off
setlocal enabledelayedexpansion

set "lstFolders=First Second"

set intCounter=0
for %%i in (!lstFolders!) do (
    set /a intCounter+= 1
    set "strFlder=%%i"
    set "strFolder!intCounter!=!strFlder!"
    echo !strFlder!
    set "varname=strFolder!intCounter!"
    for /F "delims=" %%A in (""!varname!"") do echo Indirect %%~A=!%%~A!
)

双引号避免了 FOR/F 循环的 eol 字符问题。

【讨论】:

    【解决方案2】:

    警告:以下代码仅适用于以下列表值(%lstFolders% 的标记,例如 First):

    • 不包含空格
    • 也不是以下任何字符:& | < > "

    需要一种不同的循环方法来处理这种情况。

    @echo off
    setlocal enabledelayedexpansion
    
    set "lstFolders=First Second" 
    
    set intCounter=0
    for %%i in (%lstFolders%) do (
          rem Increment the counter
        set /a intCounter += 1
          rem Echo the loop variable
        echo #!intCounter!=%%i
          rem Set variable strFolder<intCounter> to the loop variable's value
        set "strFolder!intCounter!=%%i"
          rem Echo the variable created using variable indirection with for /f ('...')
        for /f "delims=" %%v in ('echo "%%strFolder!intCounter!%%"') do set "thisFolder=%%~v"
        echo %%thisFolder%% ^(via %%strFolder!intCounter!%%^)=!thisFolder!
    )
    

    运行上述结果:

    #1=First
    %thisFolder% (via %strFolder1%)=First
    #2=Second
    %thisFolder% (via %strFolder2%)=Second
    

    您正在寻找的是可变间接

    • 虽然您可以设置间接变量(通过您从另一个变量的值动态构造的名称),例如,
      • set "strFolder!intCounter!=%%i",其中!intCounter! 的值为1,正确地将变量strFolder1 设置为%%i 的值),
    • 不能得到这样的变量值;您需要一个额外的评估步骤for /f ... ('echo ...') 可以提供。

      • for /f "delims=" %%v in ('echo "%%strFolder!intCounter!%%"') do ... 用单引号 (echo ...) 解析命令的输出,并将结果作为一个整体 (delims=) 分配给变量 %%v
        %%~v 删除了包含在 echo 参数周围的双引号,以使命令正确处理诸如 &amp; | &lt; &gt; 之类的 shell 元字符。

      • %%strFolder!intCounter!%% 立即strFolder!intCounter!评估为strFolder1,如果!intCounter!1,这要归功于封闭的加倍 @ 987654344@ 实例,以 literal %strFolder1% 结尾,这是 echo 命令在由 for 命令运行时看到的内容,导致它评估变量引用并扩展为价值。

    【讨论】:

    • 是的,我只是将您的代码放入批处理文件并运行它,查看它,现在我明白了。非常感谢,这是一个巨大的帮助。
    猜你喜欢
    • 1970-01-01
    • 2014-07-12
    • 1970-01-01
    • 2016-10-24
    • 2019-05-13
    • 2017-06-13
    • 2012-10-06
    • 1970-01-01
    相关资源
    最近更新 更多