对于带有 wmic 不需要的输出的 /F

For /F with wmic unwanted output

首先post在这里,如果我做得不对,请见谅。

我正在尝试在远程 Windows PC 上输出 OS 版本,但我不断收到不需要的数据。执行这个批处理文件:

@echo off
set /p hostname=PC hostname?
echo.
FOR /F "skip=1 tokens=*" %%A in ('wmic /node:%hostname% OS get caption') DO echo %%A
echo.
pause

Returns这个结果:

Microsoft Windows 7 Professional
Echo is off.

我能够使用 skip=1 删除 Caption 输出,但我不明白 echo 命令的来源。拆分命令没有帮助,但打开 echo 表明,循环的 wmic 命令显然在输出 OS 版本后输出 echo,所以,很明显,当 echo 关闭时,我得到最终输出:Echo is off。谁能帮我理解为什么会出现 echo 输出?

将其通过管道传递给查找命令。

@echo off
set /p hostname=PC hostname?
echo.
FOR /F "tokens=1,2 delims==" %%A in ('wmic /node:%hostname% OS get caption /value ^|find /I "caption"') DO echo %%B
echo.
pause

我建议

set "remotever="
FOR /F "skip=1 tokens=*" %%A in ('wmic /node:%hostname% OS get caption^|more') DO if not defined remotever set "remotever=%%A"
echo %remotever:~0,-1%

more 是将 wmic 的 unicode 输出转换为 ANSI 的经典批处理方法。

但是有一个问题。除了 Unicode,WMIC "ends" 它的行与 CRCRLF不是 CRLF 然后倒数第二个 CR included在分配给变量的值中(因此 echo 子字符串不包括最后一个字符 - 你会发现一些尾随空格......)。

(作为稍微简单一点的演示,尝试在您的原始版本中使用 echo q%%Aj - 您会发现 qj 覆盖)

因此,要捕获第一行,set一个变量到nothing,然后在for循环中set它到您想要捕获的值,但是用 if not defined.

门控 set

Magoo 确定了问题的根源 - WMIC unicode 输出到 ANSI 的转换存在缺陷,因为每一行都以 CRCR[=46= 结尾]LF 而不是正常的 CRLF.

FOR /F 在每个 LF 处中断(并剥离),留下 CRCR . FOR /F 当且仅当它恰好是 CR 时才从每一行中删除最后一个字符,因此在末尾留下一个 CR每行。 FOR /F 忽略空行,但 CR 不是空行,因此不需要的 Echo is off. 输出。

Magoo 和 Squashman 为您的问题提供了可行的解决方案,但它们不是适用于所有 FOR /F - WMIC 情况的通用解决方案。当 FOR /F 输出存储在变量中时会出现一个常见问题 - 不需要的 CR 通常位于值的末尾,这可能会在以后导致问题。

我们可以使用已知的 FOR /F 机制通过简单地添加一个额外的 FOR /F 来从每一行中删除不需要的 CR

所以总是有效的通用模板看起来像

for delims^=^ eol^= %%. in ('wmic ....') do for /f "whatever options you need" %%A in ("%%.") do ...

或者如果你需要跳过N行,那么

for skip^=N^ delims^=^ eol^= %%. in ('wmic ....') do for /f "whatever options you need" %%A in ("%%.") do ...

第一个 FOR /F 中的神秘语法将 DELIMS 和 EOL 都设置为空。如果您知道输出的 none 以 ; 开头,那么您可以简单地使用 "delims=""skip=N delims="。你的情况就是这样。

所以解变成:

for /f "skip=1 delims=" %%. in ('wmic /node:%hostname% OS get caption') do for /f "delims=" %%A in ("%%.") do echo %%A
@echo off
for /f "usebackq delims= skip=1" %%a in (`wmic OS get caption 2^>nul ^| findstr "."`) do set caption=%%a
for /f "usebackq delims=" %%a in (`echo %caption%`) do set caption=%%a
set "caption=%caption:~0,-1%"
echo Caption=[%caption%]