从Windows批处理中减去FOR循环索引中的1

时间:2017-02-09 04:40:14

标签: windows batch-file cmd

在Windows批处理中,我有一个for循环,如下所示:

   for /l %%a in (0,1,337) do (

      for /F "tokens=*" %%b IN ("tile%%a.jpg") DO set size=%%~zb

      if !size! GTR 0 (
          echo Size is greater than 0
      ) ELSE (

      )

   )

我知道这段代码现在没有多大意义,但我会进一步发展它。我只想知道如何在%%a语句中从ELSE中减去1。基本上我希望能够在IF不成立时“重做”一个循环数,如果这是有意义的话。感谢。

3 个答案:

答案 0 :(得分:0)

您无法修改循环变量%%a。只有循环本身才能修改它。

如果您想计算一个新值,您可以这样做:

set /A NEW_VALUE=%%a-1
echo %NEW_VALUE%           (prove that NewValue is now 1 smaller than %%a)

答案 1 :(得分:0)

您无法修改循环变量的值。您只能修改环境变量的值。

但为什么要使用for /L %%a in (0,1,337) do

更好的例如:

@echo off
for %%A in (tile*.jpg) do (
    if %%~zA == 0 (
        echo File size of %%A is 0 bytes.
    ) else (
        echo File size of %%A is greater than 0.
    )
)

此循环仅处理当前目录中的所有tile*.jpg

但是如果在当前目录中删除了具有0字节的文件,则不能使用此循环。处理当前目录中的tile*.jpg文件列表并在同一循环中更改文件列表不是一个好主意,因为根本不工作。解决方案是使用命令 DIR 首先获取与文件名模式匹配的所有文件的列表,然后使用 FOR DIR 的输出强>

@echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "delims=" %%A in ('dir /A-D /B /OS tile*.jpg 2^>nul') do (
    if %%~zA == 0 (
        echo File size of %%A is 0 bytes.
    ) else (
        echo First file with more than 0 bytes is: %%A
        goto ExitLoop
    )
)
:ExitLoop
endlocal

执行命令 DIR 以输出与模式tile*.jpg匹配的文件列表,忽略由于选项{{1}而偶然也会匹配此通配符模式的目录以裸格式(仅文件名),因为选项/A-D按顺序排序,因为选项/B从最小到最大的文件。

/OS重定向命令 DIR 输出的错误消息,以便在未找到与通配符模式匹配的任何文件 NUL 时处理 STDERR 禁止显示此错误消息。必须使用插入符2^>nul对重定向运算符>进行转义,以便在解析 FOR 命令行时将其解释为文字字符,并在执行时解释为重定向运算符DIR 命令行按 FOR

一旦找到超过0个字节的文件,就会立即退出循环,因为所有其他文件肯定也超过0个字节。

在标签^之后可以再使用一个循环,在这种情况下应该将其重命名为更合适的东西,例如在第一个循环删除文件时使用命令 REN 对其余文件重新编号0字节。

要了解使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并完全阅读为每个命令显示的所有帮助页面。

  • ExitLoop
  • dir /?
  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • if /?

有关setlocal /?的解释,请参阅Microsoft文章Using command redirection operators

答案 2 :(得分:0)

您无法修改for变量引用,例如%%a,但您可以将其值存储到标准环境变量(如index)中并对其进行修改。要使其工作,您需要启用并使用delayed expansion,因为变量在相同的代码块(即循环体)内被修改,因此请将其读取为{{1} };使用像!index!这样的常规扩展在循环开始之前返回了的值:

%index%

避免需要延迟扩展的一个不错的选择是使用嵌入式@echo off setlocal EnableDelayedExpansion for /L %%a in (0,1,337) do ( set /A "index=%%a-1" echo %%a - 1 = !index! ) endlocal 循环来获取减法的输出,并且仅在周围的for /F循环的每次迭代中迭代一次,如下所示:< / p>

for /L

这是有效的,因为@echo off for /L %%a in (0,1,337) do ( for /F %%b in ('set /A "%%a-1"') do ( echo %%a - 1 = %%b ) ) 循环在for /F上下文中执行set /A命令,在该上下文中它返回结果值 - 与上述方法形成对比,其中cmd在批处理文件上下文中执行,它不输出任何内容。