在批处理文件中,我正在检查底板信息,具有以下内容:
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
)
)
)
上述问题:当回显出来时,变量会被覆盖而不是附加到 输出:
DX79SI
This overwrites the variable
AAG28808-600
This overwrites the variable
我想要达到的目的是:
DX79SI
DX79SIThis overwrites the variable
AAG28808-600
AAG28808-600This overwrites the variable
我已花了几个小时(并将继续这样做),但我希望其他人遇到这个问题。我希望遇到这个解析问题的其他人可以在将来避免它。
由此产生的另一个问题是它似乎打破了条件逻辑。
更新
在所有的帮助之后,我想出了这个解决方案:
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%.
答案 0 :(得分:7)
首先,我无法相信批处理文件执行会发生什么。
经过多次试验,我在Windows XP SP3 x86上执行
wmic.exe baseboard get /format:list > Output.txt
并使用文件管理器Total Commander的查看器查看文件Output.txt
。我在顶部看到2条空行,但这并不重要。所以我继续进行其他试验。
后来我在文本编辑器UltraEdit中打开Output.txt
并立即在状态栏上看到 U-DOS ,表明输出文件是用UTF-16小端编码的,具有DOS行终止符。我切换到十六进制编辑模式,可以看到
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.=.
因此输出文件确实是具有UTF-16 LE BOM的Unicode文件。没有CR CR LF。所有行终止都是正确的CR LF对(回车+换行)。
现在,我在Stack Overflow上搜索批处理文件的问题,其中包含单词 wmic Unicode ,找到cmd is somehow writing chinese text as output。
dbenham的接受答案并不好,因为它创建了wmic.exe
的Unicode输出的ANSI版本,但ANSI文件现在确实包含0D 0D 0A(= CR CR LF)。 / p>
Dharma Leonardi的答案更好,因为使用命令type
的解决方案会导致Unicode输出正确转换为ANSI输出,只要输出不包含ANSI代码中不可用的字符页。
但在更改批处理代码以使用ANSI编码处理wmic.exe
的输出后,if defined BaseboardVersion
的行始终为true,尽管我看不到包含变量 BaseboardVersion 的变量任何数据,因此下一行导致显示回声状态。
我花了一些时间才发现在条件上方插入set > Variables.txt
并查看此文件,在我的计算机上,版本字符串只是一个空格字符。 版本的值是所有键的唯一值,没有字符串右边的等号只包含一个空格。
这是最终在我的计算机上工作并产生预期输出的批处理文件:
@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
答案 1 :(得分:4)
是的,你有问题,但这不是你的想法。
wmic
有一个特殊的行为:在每行输出的末尾有一个aditional回车符,也就是说,每一行都以0x0d 0x0d 0x0a
这个aditional回车符存储在你的变量中,当回显到控制台时,你得到数据和回车符,所以,如果变量后跟更多的文本,因为光标已定位在开头的line(回车),此文本在之前的回显数据上回显。
如何解决?
@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
)
)
)
在这种情况下,在不更改代码逻辑的情况下,可以使用aditional for /f
命令删除aditional回车
答案 2 :(得分:1)
正如已经回答的那样,问题在于wmic
的行结尾。
如果您不使用行尾,则可以解决此问题:wmic baseboard get Product,Version,Width
使用三个标记:产品,版本和宽度(在大多数情况下都是如此)。所以输出将是:DX79SI,AAG28808-600,
我们使用令牌1和令牌2,忽略令牌3(这会有问题)
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
我还添加了delims=,
,以防任何字符串包含空格(product
不太可能)