Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
884 views
in Technique[技术] by (71.8m points)

batch file - For /F with wmic unwanted output

First post here, so apologies if I don't do this quite right.

I'm trying to output the OS version on a remote Windows PC, but I keep getting unwanted data. Executing this batch file:

@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 this result:

Microsoft Windows 7 Professional
Echo is off.

I was able to remove the Caption output using skip=1 but I don't understand where the echo command is coming from. Splitting out the commands didn't help, but turning echo on shows that, apparently, the looped wmic command is outputting echo after outputting the OS version, so, obviously, when echo is off, I get the final output: Echo is off. Can anyone help me understand why the echo output is happening?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Magoo identified the source of the problem - the conversion of WMIC unicode output to ANSI is flawed in that each line ends with CRCRLF instead of the normal CRLF.

FOR /F breaks at (and strips) each LF, leaving CRCR. FOR /F strips the last character from each line if and only if it happens to be a CR, so that leaves one CR at the end of every line. FOR /F ignores empty lines, but CR is not an empty line, hence the unwanted Echo is off. output.

Magoo and Squashman have provided workable solutions to your problem, but they are not generic solutions that apply to all FOR /F - WMIC situations. A common issue arises when FOR /F output is stored in variables - the unwanted CR is often at the end of the value, which can cause problems later on.

We can use the known mechanics of FOR /F to strip the unwanted CR from every line by simply adding an extra FOR /F.

So the generic template that always works looks like

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

or if you need to skip N lines, then

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

The arcane syntax in the first FOR /F sets both DELIMS and EOL to nothing. If you know that none of your output begins with ;, then you can simply use "delims=", or "skip=N delims=". This is the case in your situation.

So the solution becomes:

for /f "skip=1 delims=" %%. in ('wmic /node:%hostname% OS get caption') do for /f "delims=" %%A in ("%%.") do echo %%A

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...