批处理:变量间接:通过动态构造的名称获取变量的值
Batch: variable indirection: getting the value of a variable by dynamically constructed name
所以当我运行这个代码时:
@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%!
?是否有另一种方法来引用此变量并获取其中的数据?
警告:下面的代码仅适用于列表值(%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
参数周围的双引号,以使命令正确处理 shell 元字符,例如 & | < >
)。
%%strFolder!intCounter!%%
立即计算strFolder!intCounter!
到strFolder1
,如果!intCounter!
是1
,这要归功于封闭的 doubled %
实例,最终成为 literal %strFolder1%
,这就是echo
命令通过 for
命令查看它何时为 运行,导致它评估变量引用并扩展为其值。
正如@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 字符问题。
所以当我运行这个代码时:
@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%!
?是否有另一种方法来引用此变量并获取其中的数据?
警告:下面的代码仅适用于列表值(%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
参数周围的双引号,以使命令正确处理 shell 元字符,例如& | < >
)。%%strFolder!intCounter!%%
立即计算strFolder!intCounter!
到strFolder1
,如果!intCounter!
是1
,这要归功于封闭的 doubled%
实例,最终成为 literal%strFolder1%
,这就是echo
命令通过for
命令查看它何时为 运行,导致它评估变量引用并扩展为其值。
正如@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 字符问题。