我有一个小问题,无法动动脑筋。这是代码:
SET onts=3
SET port[1]=0
SET port[2]=3
SET port[3]=2
SET free[0]=8
SET free[1]=5
SET free[2]=5
SET free[3]=15
FOR /L %%A IN (1,1,%onts%) DO (
SET /A ont[%%A]=%free[%port[%%A]%]%
)
echo %ont[1]%
echo %ont[2]%
echo %ont[3]%
我希望代码将变量0
的第一次循环迭代值port[1]
作为索引,因此访问变量free[0]
将其值8
分配给变量{{1 }}。在第二次迭代中,应使用变量ont[1]
的值3
来获取分配给变量port[2]
的变量15
的值free[3]
。并且在第三次迭代中,在从ont[2]
读取值ont[3]
之后,应使用5
的值free[2]
定义变量2
。
因此输出应为:
port[3]
但是批处理文件输出:
8
15
5
我尝试在循环中使用第二个变量:
0
3
2
但是它也不起作用。
我也尝试过调用一个函数来将此代码外包,但是仍然没有结果-我不确定,我可能做错了什么。
有人对如何使其工作有任何想法吗?
答案 0 :(得分:2)
我建议先阅读How does the Windows Command Interpreter (CMD.EXE) parse scripts?。
Windows命令处理器解析从(
开始并以匹配的)
结尾的整个命令块,并分别用环境变量的当前值替换由%variable%
完成的环境变量的所有值引用环境变量不存在。
对于命令行SET /A ont[%%A]=%free[%port[%%A]%]%
,这意味着cmd.exe
将%free[%
解释为名为free[
的环境变量的值引用,并将%]%
解释为名为环境变量的值引用]
,然后执行命令 FOR 。在 FOR 命令行上方没有定义环境变量free[
和]
,并且可以预期在启动批处理文件之前根本不存在这样的环境变量。因此,Windows命令处理器在预处理阶段之后最终将执行以下命令行:
FOR /L %A IN (1 1 3) DO (SET /A ont[%A]=port[%A] )
在运行批处理文件时,可以完全按照命令提示符窗口中的说明(通常不使用@echo off
作为第一个命令行来运行)。
一种解决方案是使用delayed expansion和另一个 FOR 循环来获取free[y]
的值,具体取决于分配给环境变量{{1 }}。
port[x]
此批处理文件的输出为:
ont[x]
要了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并非常仔细地阅读每个命令显示的所有帮助页面。
@echo off
setlocal EnableExtensions EnableDelayedExpansion
set "onts=3"
set "port[1]=0"
set "port[2]=3"
set "port[3]=2"
set "free[0]=8"
set "free[1]=5"
set "free[2]=5"
set "free[3]=15"
for /L %%A IN (1,1,%onts%) do for %%B in (!port[%%A]!) do set "ont[%%A]=!free[%%B]!"
echo %ont[1]%
echo %ont[2]%
echo %ont[3]%
endlocal
8
15
5
echo /?
endlocal /?
for /?
最后,我建议阅读Why is no string output with 'echo %var%' after using 'set var = text' on command line?上的答案
答案 1 :(得分:1)
您的方法需要两个(实际上是代码块)三个延迟扩展级别,而您没有使用。
我的previous answer演示了如何使用delayed expansion
Mofi的好answer显示了一种使用for克服双重延迟扩展的方法,
这是另一个带有伪调用的代码:
:: Q:\Test\2018\11\24\SO_53458343.cmd
@Echo off&SetLocal EnableExtensions EnableDelayedExpansion
SET onts=3
SET port[1]=0
SET port[2]=3
SET port[3]=2
SET free[0]=8
SET free[1]=5
SET free[2]=5
SET free[3]=15
FOR /L %%A IN (1,1,%onts%) DO Call SET /A "ont[%%A]=%%free[!port[%%A]!]%%"
echo ont[1]=%ont[1]%
echo ont[2]=%ont[2]%
echo ont[3]=%ont[3]%
> Q:\Test\2018\11\24\SO_53458343.cmd
ont[1]=8
ont[2]=15
ont[3]=5