windows - 解析输出时如何纠正变量覆盖错误行为?

标签 windows batch-file for-loop cmd wmic

我正在使用以下代码检查批处理文件中的底板信息。

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%

最佳答案

哇,真的很难弄清楚这里发生了什么。

首先,我无法相信批处理文件执行时会发生什么。

经过多次试验,我在 Windows XP SP3 x86 上执行了命令行

wmic.exe baseboard get /format:list > Output.txt

并使用文件管理器 Total Commander 查看文件 Output.txt
我在顶部看到两条空行,但这并不重要。所以我继续进行其他试验。

后来我在文本编辑器 UltraEdit 中打开 Output.txt 并立即在状态栏上看到 U-DOS 表明输出文件是用 UTF-16 Little Endian 编码的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.=.

所以输出文件确实是一个用带有 BOM(字节顺序标记)的 UTF-16 LE 编码的 Unicode 文件。没有 CR CR LF。所有行终止都是正确的 CR LF 对(回车 + 换行)。

现在我在 Stack Overflow 上搜索了包含单词 wmic Unicode[batch-file] 问题并找到了 cmd is somehow writing Chinese text as output

接受的 dbenham 答案并不好,因为它创建了 wmic.exe 的 Unicode 输出的 ANSI 版本,但 ANSI 文件现在确实包含 0D 0D 0A(= CR CR LF)。

Dharma Leonardi 的答案更好,因为使用命令 type 的解决方案会导致 Unicode 输出正确转换为 ANSI 输出,只要输出不包含 ANSI 代码页中不可用的字符.

注意:我在这里使用的术语 ANSI 并不是真正 100% 精确的 每个字符编码一个字节。请参阅有关 character encodingcode pageWindows code page 的维基百科文章。在 Windows 命令处理器控制台中,默认使用 OEM code page,如 437(北美国家)或 850(西欧国家)。另见 Why are Danish characters not displayed as in text editor on executing batch file? 在一个示例中解释了如何使用北美和西欧国家通常使用的各种字符编码对相同的小丹麦语文本使用哪些字节进行编码。

但是,在将批处理代码更改为使用 ANSI 编码处理 wmic.exe 的输出后,带有 if defined BaseboardVersion 的行的评估始终为 true,尽管我看不到该变量 BaseboardVersion 包含任何数据,因此下一行导致显示回显状态。

我又花了一些时间才发现在条件上方插入 set > Variables.txt 并查看此文件,在我的计算机上版本字符串只是一个空格字符。 Version 的值是所有键中唯一没有等号右边仅由一个空格组成的字符串的值。

这是最终在我的计算机上运行并产生预期输出的批处理文件:

@echo off
setlocal EnableExtensions EnableDelayedExpansion
%SystemRoot%\System32\wbem\wmic.exe /OUTPUT:"%TEMP%\UnicodeData.tmp" baseboard get /format:list
for /f "tokens=1,2* delims==" %%I in ('type "%TEMP%\UnicodeData.tmp"') do (
    if "%%I" == "Product" (
        if not "%%J" == "" if not "%%J" == " " (
            set "PlatformInfo=%%J"
            echo !PlatformInfo!
            echo !PlatformInfo!This overwrites the variable
        )
    ) else if "%%I" == "Version" (
        if not "%%J" == "" if not "%%J" == " " (
            set "BaseboardVersion=%%J"
            echo !BaseboardVersion!
            echo !BaseboardVersion!This overwrites the variable
        )
    )
)
del "%TEMP%\UnicodeData.tmp"
endlocal

关于windows - 解析输出时如何纠正变量覆盖错误行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24961755/

相关文章:

windows - 批处理可读性而不影响变量的执行

ruby-on-rails - 安装 Rails 时找不到 Gem 存储库

c - 使用 ANSI C 在 Windows 平台上传输 FTP 文件?

c++ - 获取当前进程的 HWND

c++ - 如何为 Code Blocks 13.12 编译 boost 1.55.0 至 win7(32 位)?

bash - 批处理文件和 Bash 文件有什么区别?

java - 删除arrayList中的项目: trying to delete from Index that is not there?

Python:在for循环中向迭代变量添加常量

C++11 用于在没有样板索引的情况下循环部分填充的数组?

windows - 如何重新评估批处理变量?