【问题标题】:Batch - Using Modulo in a FOR Loop - Error Operand批处理 - 在 FOR 循环中使用模 - 错误操作数
【发布时间】:2016-12-08 08:40:24
【问题描述】:

我一直在尝试使用 MOD (%%) 以便每 25 个循环执行一次 timeout /t 3 命令 我收到一个错误“无效的操作数” 代码是:

set /a var1=0
FOR /R "folder" %%G in (.) DO (
 Pushd %%G
set /a b=%%var1%% %% 25
 IF %%b%% EQU 0 (
    timeout /t 3
  )
 set /a var1=%%var1%%+1
 Popd
)

【问题讨论】:

  • 好吧,我设法摆脱了无效的操作数,但我似乎无法让模运算符工作
  • 你只需要%var1%,而不是%%var1%%
  • @SomethingDark,总的来说你是对的,但是这里需要延迟扩展(至少对于!b!)...

标签: loops batch-file modulo operand


【解决方案1】:

为什么要在% 符号对中包含变量名?读取变量的常用语法是%var1%

set /A 即使没有百分号也可以读取变量,所以请使用set /a b=var1 %% 25
另一个set /A命令行可以改成set /A var1+=1

您的代码中有一个有问题的变量,即b,因为您正在编写在同一个(带括号的)代码块中读取它,所以%b%在整个for 循环被解析,此时它很可能是空的。
对于这种情况,您需要申请delayed expansion,因此在执行时读取变量。要启用它,请使用setlocal 命令;要实际使用它,请写 !b! 而不是 %b%

这里是固定代码:

set /A var1=0
for /R "folder" %%G in (.) do (
    pushd "%%~G"
    set /A b=var1 %% 25
    setlocal EnableDelayedExpansion
    if !b! EQU 0 (
        timeout /T 3
    )
    endlocal
    set /A var1+=1
    popd
)

在这里,我将setlocalendlocal 放在循环内,以便在for 循环变量%%G 的扩展(读取)期间禁用延迟扩展,因为如果它包含感叹号,它们会丢失否则。

【讨论】:

    【解决方案2】:

    aschipfl has identified the problem and provided a fix。但是有一种非常简洁有效的方法来实现您的目标,而无需任何延迟扩展,只需使用单个 SET /A 语句。

    您可以在一个 SET /A 中组合多个计算和分配。您甚至可以在更大的表达式中使用赋值表达式的结果。

    您可以通过有意除以零来避免使用 IF 语句。当取模结果为 0 时,除法失败,通过将 stderr 重定向到 nul 来隐藏任何错误消息。条件|| 命令连接运算符仅在前面的命令失败时触发,在这种情况下除以 0 时。

    我不明白你循环的目的 - 这似乎毫无意义。但是正确的停顿是通过以下方式引入的:

    set /a var1=0
    for /r "folder" %%G in (.) do (
      pushd "%%~G"
      set /a "1/((var1+=1) %% 25)" 2>nul || timeout /t 3
      popd
    )
    

    【讨论】:

    • 偷偷摸摸!我喜欢你的回答,因为我总是学到新东西。
    • 谢谢!像魅力一样工作。
    • 另外,出于个人原因,我删除了循环之间和循环外的一些代码,所以这就是为什么您看不到我的代码的用途 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多