In a batch file, I am checking for Baseboard information, with the following:
BaseboardCheck.cmd
@echo off
setlocal enabledelayedexpansion
for /f "tokens=1,2* delims==" %%a in ('wmic baseboard get /format:list') DO (
if ["%%a"] EQU ["Product"] (
set PlatformInfo=%%b
if defined PlatformInfo (
echo.!PlatformInfo!
echo.!PlatformInfo!This overwrites the variable
)
)
if ["%%a"] EQU ["Version"] (
set BaseboardVersion=%%b
if defined BaseboardVersion (
echo.!BaseboardVersion!
echo.!BaseboardVersion!This overwrites the variable
)
)
)
The above problem: The variables get overwritten, rather than appended to, when echo'd out.
Output:
DX79SI
This overwrites the variable
AAG28808-600
This overwrites the variable
What I'd like to get to is:
DX79SI
DX79SIThis overwrites the variable
AAG28808-600
AAG28808-600This overwrites the variable
I have spent a few hours on this (and will continue to do so) but am hoping someone else has run into this issue. And am hoping anyone else who runs into this parsing problem can avoid it in the future.
The additional problem that comes out of this is that it seems to break conditional logic.
Update
After all of the assistance, I came up with this solution:
for /f "skip=2 tokens=1,2 delims=," %%a in ('wmic baseboard get Product^,Version^,Width /format:csv') do (
set Platform=%%a
set BaseboardVersion=%%b
)
echo.Platform: %Platform%
echo.Version %BaseboardVersion%.
Yes, you have a problem, but it is not what you think.
wmic
has a particular behaviour: at the end of each line output there is an aditional carriage return, that is, each line ends with 0x0d 0x0d 0x0a
This aditional carriage return is stored inside your variable and, when echoed to console, you get the data and the carriage return, so, if the variable is followed by more text, as the cursor has been positioned at the start of the line (the carriage return), this text is echoed over the previous echoed data.
How to solve?
@echo off
setlocal enabledelayedexpansion
for /f "tokens=1,* delims==" %%a in ('wmic baseboard get /format:list') DO (
if ["%%a"] EQU ["Product"] (
for /f "delims=" %%c in ("%%b") do set "PlatformInfo=%%c"
if defined PlatformInfo (
echo(!PlatformInfo!
echo(!PlatformInfo!This does not overwrite the variable
)
)
if ["%%a"] EQU ["Version"] (
for /f "delims=" %%c in ("%%b") do set "BaseboardVersion=%%c"
if defined BaseboardVersion (
echo(!BaseboardVersion!
echo(!BaseboardVersion!This does not overwrite the variable
)
)
)
In this case, without changing your code logic, an aditional for /f
command can be used to remove the aditional carriage return
Wow, it was really hard to find out what is going on here.
First, I could not believe what happens on batch file execution.
After many trials I executed on Windows XP SP3 x86
wmic.exe baseboard get /format:list > Output.txt
and looked on file Output.txt
with viewer of file manager Total Commander. I saw 2 empty lines at top, but that does not really matter. So I continued with other trials.
Later I opened Output.txt
in text editor UltraEdit and saw immediately on status bar U-DOS indicating that the output file is encoded in UTF-16 little endian having DOS line terminators. I switched to hex edit mode and could see
00000000h: FF FE 0D 00 0A 00 0D 00 0A 00 43 00 61 00 70 00 ; ÿþ........C.a.p.
00000010h: 74 00 69 00 6F 00 6E 00 3D 00 ; t.i.o.n.=.
So the output file is indeed a Unicode file with UTF-16 LE BOM. There is no CR CR LF. All line terminations are correct the CR LF pair (carriage return + line-feed).
Now I searched on Stack Overflow for questions with batch-file containing the words wmic Unicode and found cmd is somehow writing chinese text as output.
The accepted answer of dbenham is not good as it creates an ANSI version of the Unicode output of wmic.exe
, but the ANSI file contains now indeed 0D 0D 0A (= CR CR LF).
Better is the answer by Dharma Leonardi as the solution with using command type
results in a correct conversion of the Unicode output to ANSI output as long as the output does not contain characters not available in ANSI code page.
But after changing the batch code to process output of wmic.exe
with ANSI encoding, the line with if defined BaseboardVersion
evaluated always to true although I could not see that variable BaseboardVersion contained any data and therefore next line resulted in showing echo status.
It took me again some time to find out with inserting set > Variables.txt
above the condition and looking on this file that on my computer the version string is just a single space character. The value of Version was the only value of all keys without a string right of the equal sign consisting only of a single space.
Here is the batch file which finally worked on my computer and produces the expected output:
@echo off
setlocal enabledelayedexpansion
wmic.exe /OUTPUT:"%TEMP%\UnicodeData.tmp" baseboard get /format:list
for /f "usebackq tokens=1,2* delims==" %%a in (`type "%TEMP%\UnicodeData.tmp"`) do (
if "%%a" == "Product" (
if not "%%b" == "" if not "%%b" == " " (
set "PlatformInfo=%%b"
echo !PlatformInfo!
echo !PlatformInfo!This overwrites the variable
)
) else if "%%a" == "Version" (
if not "%%b" == "" if not "%%b" == " " (
set "BaseboardVersion=%%b"
echo !BaseboardVersion!
echo !BaseboardVersion!This overwrites the variable
)
)
)
del "%TEMP%\UnicodeData.tmp"
endlocal
As already answered, the problem is with the line-endings of wmic
.
You can overcome this problem if you don't use the end of the line: wmic baseboard get Product,Version,Width
uses three tokens: Product, Version and Width (which is empy in most cases). So the Output will be: DX79SI,AAG28808-600,
We are using token 1 and token 2, ignoring token 3 (this would have the problem)
set Platform=undefined
set BaseboardVersion=undefined
for /f "tokens=1,2 delims=," %%a in ('wmic baseboard get Product^,Version^,Width^|findstr "."') do (
set Platform=%%a
set BaseboardVersion=%%b
)
echo it is a %Platform% with Version %BaseboardVersion%. No overwriting
I also added delims=,
in case any of the strings contains a space (not unlikely with product
)
来源:https://stackoverflow.com/questions/24961755/how-to-correct-variable-overwriting-misbehavior-when-parsing-output