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

问题描述 投票:4回答:3

在批处理文件中,我正在检查底板信息,具有以下内容: 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 batch-file for-loop cmd wmic
3个回答
4
投票

是的,你有问题,但这不是你的想法。

wmic有一个特殊的行为:在每行输出的末尾有一个aditional回车,也就是说,每一行以0x0d 0x0d 0x0a结尾

这个aditional回车符存储在你的变量中,当回显到控制台时,你得到数据和回车符,因此,如果变量后跟更多的文本,因为光标已经定位在行的开头(回车),此文本与之前的回显数据相呼应。

怎么解决?

@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
        )
    )   
)

在这种情况下,在不更改代码逻辑的情况下,可以使用额外的qazxsw poi命令来删除aditional回车


7
投票

哇,真的很难找到这里发生的事情。

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

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

for /f

并查看文件管理员Total Commander的文件wmic.exe baseboard get /format:list > Output.txt 。我在顶部看到2条空行,但这并不重要。所以我继续进行其他试验。

后来我在文本编辑器UltraEdit中打开Output.txt并立即在状态栏U-DOS上看到输出文件是用UTF-16小端编码的,具有DOS行终止符。我切换到十六进制编辑模式,可以看到

Output.txt

因此输出文件确实是具有UTF-16 LE BOM的Unicode文件。没有CR CR LF。所有行终止都是正确的CR LF对(回车+换行)。

现在,我在Stack Overflow上搜索包含单词wmic Unicode并找到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.=. 的批处理文件的问题。

接受的cmd is somehow writing chinese text as output答案并不好,因为它创建了dbenham的Unicode输出的ANSI版本,但ANSI文件现在确实包含0D 0D 0A(= CR CR LF)。

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

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

我花了一些时间才发现插入if defined BaseboardVersion超出条件并查看此文件在我的计算机上版本字符串只是一个空格字符。 Version的值是所有键的唯一值,没有字符串右边的等号只包含一个空格。

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

set > Variables.txt

1
投票

正如已经回答的那样,问题在于@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 的行尾。

如果不使用行的末尾,则可以解决此问题:wmic使用三个标记:Product,Version和Width(在大多数情况下都是empy)。所以输出将是:wmic baseboard get Product,Version,Width我们使用令牌1和令牌2,忽略令牌3(这会有问题)

DX79SI,AAG28808-600,

我还添加了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=,

© www.soinside.com 2019 - 2024. All rights reserved.