Batch file 如何在批处理脚本中增加循环变量?

Batch file 如何在批处理脚本中增加循环变量?,batch-file,scripting,Batch File,Scripting,在我上面的代码示例中-如何在for循环中获取变量(如%%j),并在for循环中递增自身(如%%j++)?我目前的解决方案(很混乱,我不喜欢)是创建一个新变量,并将其设置为%%j的值,然后递增该变量并开始使用该变量,如下所示: ::Compare with available valid arguments FOR /L %%i IN (1,1,!avArgc!) DO ( FOR /L %%j IN (1,1,!argc!) DO ( IF !avArgv[%%i]!==

在我上面的代码示例中-如何在for循环中获取变量(如
%%j
),并在for循环中递增自身(如
%%j++
)?我目前的解决方案(很混乱,我不喜欢)是创建一个新变量,并将其设置为
%%j
的值,然后递增该变量并开始使用该变量,如下所示:

::Compare with available valid arguments
FOR /L %%i IN (1,1,!avArgc!) DO (
    FOR /L %%j IN (1,1,!argc!) DO (
        IF !avArgv[%%i]!==!argv[%%j]! (
            echo Match: !avArgv[%%i]!

            ::Check the next option
            SET /A nextArg=%%j
            SET /A nextArg+=1
            FOR /L %%n IN (!nextArg!,1,!nextArg!) DO ( 
                IF !nextArg! LEQ !argc! ( 
                    echo next arg: !argv[%%n]!
                    call :CheckSubOption
                )
            ) 
        )
    )
)

这种情况的一般解决方案是不依赖于循环/if中的块,而是在不受计算级别阻止的情况下使用子例程

::Check the next option
SET /A nextArg=%%j
SET /A nextArg+=1

观察您的代码和意图,您似乎希望在循环结构中跳过数字。然而,你想要改变它的方式会破坏稳定。在大多数脚本语言(如matlab、bash和batch)中,for循环中使用的变量用作循环中的参考框架当您告诉代码运行特定的for循环时,无论其参数是否更改,它都将运行该计算。一个真实的例子是一位教授正在使用过时的数字来解决问题,直到第二天他才收到新的数字。教授不能相应地改变他的答案,因为他还没有新的数据

这并不意味着这个问题无法解决。事实上,有多种方法可以实现这一点。第一个稍微复杂一点的是嵌套的For结构

FOR /L %%i IN (1,1,!avArgc!) DO call :Loop1 %%i
goto :EOF

:Loop1
FOR /L %%j IN (1,1,!argc!) DO call :Loop2 %1 %%j
goto :EOF

:Loop2
IF !avArgv[%1]!==!argv[%2]! (
            echo Match: !avArgv[%1]!

            ::Check the next option
            SET /A nextArg=%2+1
            call :CheckOpt %nextArg%
)
goto :EOF

:CheckOpt
IF %1 LEQ %argc% ( 
    echo next arg: !argv[%1]!
    call :CheckSubOption
)
运行程序时,如果
maxlength
变量大于3,则变量
next
将跳过值3

  • 之所以如此,是因为嵌套for循环只运行一次 整个for循环的每次迭代
。这使程序有时间重置其使用的数据,这要归功于
call
命令,该命令是更新变量的一种方式。然而,这是非常低效的,可以用更少的代码行来完成

第二个示例使用GOTO和if语句

@echo off
set /p maxLength=[Hi times?]
set skip=0

FOR /L %%i IN (1,1,%maxLength%) DO (call :subroutine %%i)

echo alright im done.
pause 
GOTO :eof

rem the below code uses a for loop structure that only loops 1 time based on the passed argument from the overall for loop as so to make changes to how its run.

:subroutine
set /a next=%1+%skip%
 FOR /L %%r IN (%next%,1,%next%+1) DO (call :routine %%r)
 GOTO :eof

:routine
if %1==3 (set /a skip=1)
echo %skip%
echo %next%
echo %1
pause
GOTO :eof
这段代码基本上会回显每次递增的x值,直到它达到10为止。但是,当它达到4时,增量将增加1,因此每次运行循环时,x值将增加2。根据您的需要,您希望能够更改
%%j
的值的递增方式,这是无法做到的,因为
%%j
是一个for循环在其计算中的位置的语句。for循环和goto语句除了如何处理它们之外,在实现什么方面没有区别


很遗憾,我还没有正确的代码形式,但我知道我给出的代码示例可以用来实现您的特定愿望。

%%j
使用
for
循环进行解析。这意味着,在循环中它已经被解析,所以它是一个固定值,而不是一个可以更改的变量。恐怕你不得不忍受这个混乱的新变量。
SET/A nextArg=%%j
,不需要
/A
。这不应该造成伤害,但应该避免。另外,我怀疑这是为了我们的缘故而放进去的,但是使用
::检查下一个选项
,不要在代码块中放
命令,只要
rem
。可以通过调用带有引用变量的外部标签来更改它,但老实说,这比添加新变量更麻烦。谢谢Stephen回答了我的问题@areset
::
rem
是可交换的,因此可以在代码块内使用它们。代码与我的
::
一样工作,添加注释的方式加上
更容易识别。@ShadyProgrammer否,
rem
是实际命令,
是带有无效起始字符的标签,并显示
::
的问题,即使速度更快,但如果将其放在代码块中,可能会非常不可预测。谢谢,我的最终解决方案似乎会像在这里提问之前一样混乱。你已经用黑体字的句子回答了我的问题,并给了我一个想法去尝试GOTO&IF语句组合在一起而不是for循环。不客气。请记住,有时不同的代码集可能更适合您的需要。强制命令执行并非专门为处理而构建的操作并不总是一个好主意。如果您希望在for循环期间修改变量并在外部快速更新,请记住for循环仅在本地运行。您需要在代码开头运行
setlocal enabledelayedexpansion
,以允许基于运行的函数更新变量。因此,如果您有一个运行
集n+=1的for循环,您可以使用
!n
在for循环期间调用新更新的变量。请不要再查看。它在语法上不如其他脚本语言(如bash脚本)优雅,但它的简单性和与其他微软功能的集成使它成为一种非常有用的学习语言。如果你没有账户,可以是模拟按键或youtube视频播放列表。考虑到大多数人使用windows(它所看到的病毒数量的证据),批处理脚本在很大程度上是可移植的,并且可以修改为与任何其他语言一样好。好的建议,虽然我觉得这会使我的代码从杂乱无章变为各种各样的杂乱无章,但我会用它来整理我的整体代码结构。非常感谢。
@echo off
set jump=1
:heyman
set /A "x+=%jump%"
if %x%==4 (set /A "jump=2")
echo %x%
if %x% LSS 10 goto heyman
echo done!