我想运行命令并在批处理文件中总结输出。这是代码:
@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条件下检查空白/空值的文章,但似乎都没有。
答案 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。