通过在Windows批处理文件for循环中跳过空白/空值来汇总命令输出

时间:2016-06-22 05:52:00

标签: batch-file

我想运行命令并在批处理文件中总结输出。这是代码:

@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条件下检查空白/空值的文章,但似乎都没有。

2 个答案:

答案 0 :(得分:2)

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 来处理行作为命令< strong> 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 /?

答案 1 :(得分:1)

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