我正在处理一个批处理文件,该文件应显示当前估计的剩余费用。但是当我运行命令时,我得到了期望的结果以及错误消息Missing operand.
的输出。
我的代码:
FOR /F "delims= skip=1" %%i IN ('WMIC PATH Win32_Battery Get EstimatedChargeRemaining') DO (SET /a CHR=%%i)
ECHO "Battery Level: %CHR%"
如何摆脱不需要的输出Missing operand.
?
我已经尝试从最后一部分(即%
)中删除DO (SET /a CHR=i)
,但是当我这样做时,我最终得到的是"Battery Level: 0"
,好像它跳过了其中的一些数字一样。结果。
答案 0 :(得分:4)
Windows Management Instrumentation Command-line实用程序输出文本UTF-16用byte order mark(BOM)编码的Little Endian,这意味着(几乎)每个字符总是两个字节,而没有显示FF FE
(BOM输出文本开头的十六进制字节。
FOR 设计用于使用ASCII / ANSI / OEM编码来解析文本,这些编码为character encodings,每个字符仅使用一个字节。通过在命令提示符窗口中运行命令chcp
来输出使用的代码页,该命令确定哪个字符由一个字节表示,其值的范围从十进制0
到255
或十六进制00
到FF
。默认情况下,Windows命令行环境中使用的代码页取决于为使用的用户帐户设置的区域/国家/地区。
让我们看看发布的代码:
FOR /F "delims= skip=1" %%i IN ('WMIC PATH Win32_Battery Get EstimatedChargeRemaining') DO (SET /a CHR=%%i)
ECHO "Battery Level: %CHR%"
例如,wmic
的输出中,¶
表示Windows 7和Windows XP上的回车+换行符:
EstimatedChargeRemaining ¶
93 ¶
此输出重定向到文件中并以十六进制查看,如下所示:
0000h: FF FE 45 00 73 00 74 00 69 00 6D 00 61 00 74 00 ; ÿþE.s.t.i.m.a.t.
0010h: 65 00 64 00 43 00 68 00 61 00 72 00 67 00 65 00 ; e.d.C.h.a.r.g.e.
0020h: 52 00 65 00 6D 00 61 00 69 00 6E 00 69 00 6E 00 ; R.e.m.a.i.n.i.n.
0030h: 67 00 20 00 20 00 0D 00 0A 00 39 00 33 00 20 00 ; g. . .....9.3. .
0040h: 20 00 20 00 20 00 20 00 20 00 20 00 20 00 20 00 ; . . . . . . . .
0050h: 20 00 20 00 20 00 20 00 20 00 20 00 20 00 20 00 ; . . . . . . . .
0060h: 20 00 20 00 20 00 20 00 20 00 20 00 20 00 0D 00 ; . . . . . . ...
0070h: 0A 00 ; ..
格式为:十六进制偏移量:十六进制字节; Windows-1252字符表示形式
上面的代码导致在单独的命令过程中跳过wmic
输出的第一行,该命令过程由 FOR 使用cmd.exe /C
通过使用环境变量ComSpec
FOR 捕获,仅显示值名称EstimatedChargeRemaining
。
第二行包含感兴趣的值,该值包含一个,两位或三位数字,取决于该值的数字,它们之间有21到23个空格,首先分配给循环变量i
,然后分配给环境变量CHR
使用算术表达式忽略尾随空格。
根据Stephan对您先前的问题How to get value without unwanted spaces in WMIC results?的评论编写的这段代码在Windows XP上可以完美运行,但在Windows 7上会出现错误消息:
缺少操作数。
在Windows XP上,只有一个循环迭代,即为值93
分配22个尾随空格,并将回车符返回到环境变量CHR
,其中空格和回车符被命令< strong> SET (由于算术表达式)。
但是在Windows 7上,第二次运行循环,只是将回车分配给了循环变量i
。在算术表达式的求值时,命令 SET 忽略了垂直空格字符回车,该结果导致在第二个循环迭代set /a CHR=
上执行,因此确实缺少等号后的操作数语法正确的算术表达式。
此问题 FOR 在解析UTF-16编码输出时有多种解决方案。
一个很简单的方法是在将感兴趣的值分配给环境变量后退出 FOR 循环。
for /F "skip=1" %%I in ('%SystemRoot%\System32\wbem\wmic.exe PATH Win32_Battery GET EstimatedChargeRemaining') do set "CHR=%%I" & goto HaveValue
:HaveValue
echo Battery level: %CHR%%%
因此, FOR 循环仅迭代一次,并且仅处理wmic
输出的第二行,其中包含感兴趣的值和尾随空格。选项delims=
用于定义一个空的定界符列表,不用于获取 FOR 已处理从{{ 1}},因此循环变量wmic
已经拥有感兴趣的值,没有尾随空格。这样就可以省略 SET 参数I
,而无需使用算术表达式即可将值仅分配给环境变量。
解决由 FOR 输出的/A
的UTF-16编码行尾错误解析而解决此问题的另一种简单解决方案,是使用如下代码:
wmic
例如,带有选项for /F "tokens=2 delims==" %%I in ('%SystemRoot%\System32\wbem\wmic.exe PATH Win32_Battery GET EstimatedChargeRemaining /VALUE') do set "CHR=%%I"
echo Battery level: %CHR%%%
的{{1}}的输出是wmic
代表回车+换行符:
/VALUE
此输出重定向到文件中并以十六进制查看,如下所示:
¶
因此开头有两个空行,即使使用UTF-16编码,它们也总是被 FOR 忽略。然后是包含值名称和值之间带有等号的行。最后还有两个空行。
这两个 FOR 选项¶
¶
EstimatedChargeRemaining=93¶
¶
¶
导致第三行在等号处分割,仅在等号后将第二个字符串分配给循环变量{{1} },该变量仅在环境变量0000h: FF FE 0D 00 0A 00 0D 00 0A 00 45 00 73 00 74 00 ; ÿþ........E.s.t.
0010h: 69 00 6D 00 61 00 74 00 65 00 64 00 43 00 68 00 ; i.m.a.t.e.d.C.h.
0020h: 61 00 72 00 67 00 65 00 52 00 65 00 6D 00 61 00 ; a.r.g.e.R.e.m.a.
0030h: 69 00 6E 00 69 00 6E 00 67 00 3D 00 39 00 33 00 ; i.n.i.n.g.=.9.3.
0040h: 0D 00 0A 00 0D 00 0A 00 0D 00 0A 00 ; ............
旁边分配。由于在tokens=2 delims==
输出末尾解析的空行错误,命令 SET 仅执行一次,结果仅在一个子字符串中被 FOR 找到回车符由于没有第二个子字符串,因此它无法为循环变量I
分配任何内容。因此, FOR 不会第二次执行命令 SET 。
npocmaka以answer on your previous question的形式发布了另一种简单的解决方案,方法是使用第二个 FOR 循环来处理感兴趣的值正确的行。
其他解决方案使用附加文件或附加命令将UTF-16编码的文本输出为ASCII编码的文本, FOR 可以捕获和处理这些文本而没有任何问题。有关此类解决方案,请参见How to correct variable overwriting misbehavior when parsing output?上的答案。
要了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并非常仔细地阅读每个命令显示的所有帮助页面。
CHR
wmic
I
echo /?
for /?
goto /?
set /?
wmic /?
答案 1 :(得分:3)
之所以发生这种情况,是因为WMIC输出中的100之后有行。 WMIC为我输出4条线。它将跳过第一行,然后继续其他行,其中只有一条有效。
@echo off
FOR /F "delims= skip=1" %%i IN ('WMIC PATH Win32_Battery Get EstimatedChargeRemaining') DO (
SET /a CHR=%%i
goto loopdone
)
:loopdone
ECHO "Battery Level: %CHR%"