![X](https://linux22.com/image/1596462/X.png)
我通读并尝试了此主题中的解决方案:批处理文件。变量中的变量但这超出了我的理解范围,或者对我来说它不起作用。
我有一个.ini
如下所示的文件:
rep1=VAL
url1=VAL
rep2=VAL
url2=VAL
︙
在我的批处理文件中,我将这些值保存到变量中:rep1 保存到 %rep1%,url1 保存到 %url1% 等等。此.ini
文件中的项目数应该会根据需要而改变,因此我需要读取整个文件。
然后,我想在“for”循环中对每组两个项目执行一个命令,如下所示:
program.exe -param1 %rep1% -param2 %url1%
因此,在下一次循环迭代中,它将是:
program.exe -param1 %rep2% -param2 %url2%
依此类推,直到文件用完.ini
。问题是,我无法在命令中将计数器“插入”到变量中。我尝试用计数器替换数字,方法是:
%rep%%counter%
但它不会调用 %repX%,其中“X”是数字,变量如预期的那样。
有什么方法可以在批处理文件中做到这一点吗?
我当前的代码:
Set _File=list.ini
Set /a _Lines=0
For /f %%j in ('Find "" /v /c ^< %_File%') Do Set /a _Lines=%%j
::counting how many times for loop to go
set /a iterate=(%_Lines%-1)/2
::read the ini file
for /f "delims=" %%a in (list.ini) do set %%a
setlocal enableextensions enabledelayedexpansion
set /a count = 1
FOR /L %%I IN (1,1,%iterate%) DO (
set "rep=%rep%%count%"
set "url=%url%%count%"
program.exe -param1 %rep% -installIU %url%
set /a count += 1
)
当我在命令前放置 echo 时,%rep% 和 %url% 似乎为空,而我尝试在第一次迭代时使它们变为 %rep1% 和 %url1%,并在每次循环时增加数字。
答案1
作为Twisty Impersonator 说,你可能正在处理XY问题。
X
给定一个输入文件
rep1=The
url1=quick
rep2=brown
url2=fox
︙
你想运行如下命令
program.exe -param1 The -installIU quick
program.exe -param1 brown -installIU fox
︙
我会这样做:
setlocal enabledelayedexpansion
set phase=1
for /f "delims== tokens=1*" %%A in (list.ini) do (
if !phase! == 1 (
set "saverep=%%B"
set phase=2
) else (
program.exe -param1 "!saverep!" -installIU "%%B"
set phase=1
)
)
该for
语句将第一个 之前的所有内容读入=
并将%%A
其后的所有内容读入%%B
。 (任一值都可能包含空格。我们不希望%%A
包含空格,因为它将是 或 。该 值可能包含其他 符号。)变量在和 之间交替。当我们读取 a 时 是 ,而 当我们读取 a 时是 。repN
urlN
%%B
=
phase
1
2
1
repN
2
urlN
当我们读取 a 时 (当为 时),将值保存在(并设置为)。当我们读取 a 时 (当为 时),使用保存的 rep 和当前行的 URL 值运行。我添加了引号( 和 )来处理其中带有空格的值。repN
phase
1
saverep
phase
2
urlN
phase
2
program
"!saverep!"
"%%B"
这完全忽略了文件中的变量名称(即 出现在 左侧的和 字符串),即使我们可以访问它们(在 中 )。如果您担心文件中可能存在数据完整性问题(跳过的条目、无效的条目、多行条目等),您当然可以添加代码来对 进行健全性检查。repN
urlN
=
%%A
%%A
是
给定一个输入文件
rep1=The
url1=quick
rep2=brown
url2=fox
︙
您想要读取文件,在环境中设置变量rep1
= The
,url1
= quick
,
rep2
= brown
,url2
=等...,然后循环遍历这些环境变量并运行如下命令fox
program.exe -param1 The -installIU quick
program.exe -param1 brown -installIU fox
︙
以下是实现此目的的方法:
Set /a _Lines=0
For /f %%j in ('Find "" /v /c ^< %_File%') Do Set /a _Lines=%%j
::counting how many times for loop to go
set /a iterate=(%_Lines%-0)/2
::read the ini file
for /f "delims=" %%a in (list.ini) do set %%a
setlocal enableextensions enabledelayedexpansion
FOR /L %%I IN (1,1,%iterate%) DO (
set count=%%I
call set "rep=%%rep!count!%%"
call set "url=%%url!count!%%"
program.exe -param1 "!rep!" -installIU "!url!"
)
这显然与您现在拥有的非常接近。注意:
- 您可能不需要这样做
Set /a _Lines=0
(即,您可能只需省略该行)。 - 您可能想验证命令
_Lines
后的值是否有效For … ('Find …) …
。如果真的偏执,您可以将其初始化_Lines
为完全无效的值(例如none
或null
)。如果 命令_Lines
后仍然是初始值For … ('Find …) …
,则表示失败。如果_Lines
不是偶数正整数,则说明有问题。- 如果
_Lines
是0
(零)或奇数正整数,则说明您的文件有问题。 - 如果
_Lines
是其他值(负数、非整数如3.14
,或非数字如foo
),则该命令有问题Find
。
- 如果
- 我设置
iterate
为 ,以便明显地表明我做了更改。我相信你应该能够这样做。毕竟,如果文件长 42 行,那么你就有 21 个数据点(即 21(%_Lines%-0)/2
set /a iterate=%_Lines%/2
对的值,需要执行 21 个命令),对吗?
如果您有充分的理由减去一个,那么请将其放-1
回去(但您可能希望记录下原因,即使只是作为代码中的注释)。 - 我把它留在那里
enableextensions
,因为你有它,但是,据我所知,你不需要它。 - 因为我们正在做一个
FOR /L
循环,所以我们不会还需要对变量进行算术运算count
;只需将其设置为等于循环索引。 最后,回报:
call set "rep=%%rep!count!%%" call set "url=%%url!count!%%"
如果
count
是(例如)17
,则第一个命令将构建一个类似于的字符串"rep=%rep17%"
。然后我们“调用”该set "rep=%rep17%"
命令,该命令重新解析/重新解释/评估该命令并设置rep
为等于的值%rep17%
。(显然第二行对做了完全相同的事情url
。)call
我从以下地址得到了这种使用语句的方法壁球手的回答批次增量变量字符串。其他主题讨论了变体;例如, 批处理文件。变量中的变量 (尽管并非所有该问题的答案都是循环的)。
是2
如果我这样表达的话,上面的后半部分可能会更清楚:
setlocal enabledelayedexpansion
FOR /L %%I IN (1,1,%iterate%) DO (
call :kludge rep%%I url%%I
program.exe -param1 "!rep!" -installIU "!url!"
)
goto :eof
:kludge
set "rep=!%1!"
set "url=!%2!"
exit/b
在这里,我们构建像 rep17
和这样的字符串url17
,并将它们传递给:kludge
子程序,在子程序中对它们进行重新解析
set "rep=!rep17!"
set "url=!url17!"
请注意,此解决方案消除了count
变量。
哎呀!
下面是另一个更短的变体,尽管可能不太清楚:
setlocal enabledelayedexpansion
FOR /L %%I IN (1,1,%iterate%) DO (
call set "rep=%%rep%%I%%"
call set "url=%%url%%I%%"
program.exe -param1 "!rep!" -installIU "!url!"
)
这个神秘的表达式%%rep%%I%%
解析如下:
%%rep%%I%%
▲▲ ↑-↑▲▲
▲▲______▲▲
- 首先,
%%I
被识别为循环索引变量并用其值(例如,17)替换,从而得到类似的字符串%%rep17%%
。 - 其余的
%%
对简化为单个%
字符:%rep17%
。 - 该
%rep17%
表达式被解释为第 17 个rep
变量。
请注意,该解决方案还避免使用count
变量。