【问题标题】:Sum up command output by skipping blank/null values in Windows batch file for loop通过跳过 Windows 批处理文件 for 循环中的空白/空值来总结命令输出
【发布时间】:2016-06-22 05:51:59
【问题描述】:

我想运行一个命令并将输出汇总到一个批处理文件中。代码如下:

@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
SET NoOfCores=0
FOR /F "skip=1 USEBACKQ" %%G IN (`wmic cpu get NumberOfLogicalProcessors`) DO (
    IF NOT "%%G" == "" (
        SET /A NoOfCores = !NoOfCores! + %%G
    )
)
echo NoOfCores:%NoOfCores%
ENDLOCAL

当我运行这个批处理文件时,我得到了正确的输出以及一个错误:

Missing operand.
NoOfCores:8

当我手动运行命令 wmic cpu get NumberOfLogicalProcessors 时,我得到如下输出:

NumberOfLogicalProcessors
4
4

谁能告诉我如何跳过输出中的最后一个空白行?

我已经参考了几篇关于在 IF 条件下检查空白/空值的文章,但似乎没有一个有效。

【问题讨论】:

    标签: batch-file


    【解决方案1】:

    wmic 的输出采用 UTF-16 Little Endian 编码,导致通过命令 FOR 解析时出现问题。

    FOR 命令将文件从 Unicode 转换为单字节编码文本时的结尾解释为 回车 回车换行。错误的回车使最后一行不为空。在提供的批处理代码中,这导致IF NOT "%%G" == "" 为真,因为循环变量包含回车。但是计算算术表达式的命令 SET 将回车解释为空白字符,因此确实缺少加法的第二个操作数。

    但是在命令提示符窗口中运行批处理文件时看不到所有这一切,@echo on 在第一行,因为在写入控制台窗口时,每个回车符都会被流写入器删除。

    更多详情请查看How to correct variable overwriting misbehavior when parsing output上的答案。

    一种解决方法是首先将 wmic 的输出重定向到一个临时文件中,然后使用 FOR 中的命令 TYPE 将这些行作为命令 TYPE 在从 Unicode 到 OEM 的转换方面比命令 FOR 做得更好。处理完行后临时文件被删除。

    @echo off
    setlocal EnableDelayedExpansion
    %SystemRoot%\System32\wbem\wmic.exe cpu get NumberOfLogicalProcessors >"%TEMP%\NumberOfLogicalProcessors.tmp"
    set "NoOfCores=0"
    for /F "skip=1" %%G in ('type "%TEMP%\NumberOfLogicalProcessors.tmp"') do set /A NoOfCores+=%%G
    del "%TEMP%\NumberOfLogicalProcessors.tmp"
    echo NoOfCores: %NoOfCores%
    endlocal
    

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

    • del /?
    • echo /?
    • endlocal /?
    • for /?
    • set /?
    • setlocal /?
    • type /?
    • wmic cpu get /?

    【讨论】:

      【解决方案2】:

      Mofi's answer 很好地解释了这里发生的事情并为此提供了解决方案。

      还有一种更简单的方法:放置另一个for /F 循环来第二次解析第一个循环的输出,以消除孤立的回车字符。这是正确解析 Unicode 文本的最简单、最通用的解决方案。

      所以这是我要使用的代码:

      @echo off
      set /A NoOfCores=0
      for /F "skip=1" %%G in ('wmic cpu get NumberOfLogicalProcessors') do (
          for /F %%H in ("%%G") do (
              set /A NoOfCores+=%%G
          )
      )
      echo NoOfCores: %NoOfCores%
      

      此方法归功于dbenham -- 请参阅他对Why is the FOR /f loop in this batch script evaluating a blank line? 的回答以及他的外部文章WMIC and FOR /F : A fix for the trailing <CR> problem

      【讨论】:

        猜你喜欢
        • 2013-03-12
        • 1970-01-01
        • 1970-01-01
        • 2023-03-19
        • 1970-01-01
        • 1970-01-01
        • 2021-07-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多