X

X

我通读并尝试了此主题中的解决方案:批处理文件。变量中的变量但这超出了我的理解范围,或者对我来说它不起作用。

我有一个.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 时是 。repNurlN%%B=phase121repN2urlN

当我们读取 a 时 (当为 时),将值保存在(并设置为)。当我们读取 a 时 (当为 时),使用保存的 rep 和当前行的 URL 值运行。我添加了引号( 和 )来处理其中带有空格的值。repNphase1saverepphase2urlNphase2program"!saverep!""%%B"

这完全忽略了文件中的变量名称(即 出现在 左侧的和 字符串),即使我们可以访问它们(在 中 )。如果您担心文件中可能存在数据完整性问题(跳过的条目、无效的条目、多行条目等),您当然可以添加代码来对 进行健全性检查。repNurlN=%%A%%A

给定一个输入文件

rep1=The
url1=quick
rep2=brown
url2=fox

您想要读取文件,在环境中设置变量rep1= Theurl1= quickrep2= brownurl2=等...,然后循环遍历这些环境变量并运行如下命令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不是偶数正整数,则说明有问题。
    • 如果 _Lines0(零)或奇数正整数,则说明您的文件有问题。
    • 如果 _Lines是其他值(负数、非整数如3.14,或非数字如foo),则该命令有问题Find
  • 我设置iterate为 ,以便明显地表明我做了更改。我相信你应该能够这样做。毕竟,如果文件长 42 行,那么你就有 21 个数据点(即 21 (%_Lines%-0)/2set /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变量。

相关内容