删除WMIC的最后一个属性值处的空间并添加另一个字符串

时间:2019-06-09 02:24:50

标签: cmd wmic

对不起,我的英语不好。 我想在WMIC的最后一个Property值处删除空间,并添加另一个字符串。

del /f /q "GPU.txt"
for /f "skip=2 tokens=2,3,4 delims=," %%a in ('"wmic path Win32_VideoController get Caption,CurrentHorizontalResolution,CurrentVerticalResolution /format:csv"') do (
    SETLOCAL EnableDelayedExpansion
    For %%# in (*) do (
        SET var=%%~n#
        Set MyVar=!var!
        set MyVar=!MyVar: =!
    )
    echo %%a (%%b x !MyVar!)>>"GPU.txt"
)

无显示。 谢谢。

1 个答案:

答案 0 :(得分:0)

为什么相关代码不起作用?

  1. 请阅读this answer,以获取有关命令 SETLOCAL ENDLOCAL 的详细信息。在 FOR 循环中使用 SETLOCAL 时,强烈建议在同一 FOR 循环或堆栈中也使用 ENDLOCAL 循环执行期间可能发生溢出。在这里不会发生这种情况,因为循环迭代不多,但是 ENDLOCAL 仍应在包含 SETLOCAL 的同一 FOR 循环中使用。

  2. 问题代码中的
  3. For %%# in (*) do处理当前目录中未隐藏文件的每个文件名。没有文件扩展名的文件名被分配给环境变量var。接下来,将此变量分配给另一个变量MyVar,而无需进行任何修改,除了行Set MyVar=!var!包含尾随空格或制表符。最后,从文件名环境变量MyVar的字符串值中删除所有空格。

    我不知道这个用于处理当前目录中文件名的 FOR 循环与视频控制器的名称以及当前的水平和垂直分辨率有什么关系。

    我建议阅读Why is no string output with 'echo %var%' after using 'set var = text' on command line?

  4. 上的答案
  5. 命令行)中的右括号echo %%a (%%b x !MyVar!)>>"GPU.txt"被解释为第一个 FOR 的命令块结尾。有必要使用)来转义^并使用echo %%a (%%b x !MyVar!^)>>"GPU.txt"来获取由cmd.exe解释为文字字符的右括号,并由echo解析整个文本时输出在第一个 FOR 命令行上以(开头的命令块。

  6. wmic.exe输出文本UTF-16 Little Endian(每个字符两个字节),而不是ANSI编码(每个字符一个字节)。 FOR 分别cmd.exe在解释Unicode编码的字符流方面存在错误,例如在How to correct variable overwriting misbehavior when parsing output?

    中有详细解释

    您认为垂直分辨率值末尾有一个空格,实际上是在回车符后面附加了回车符,这是因为分别通过命令 FOR 处理wmic.exe的Unicode输出{ {1}}。

什么是有效代码,为什么起作用?

此任务的一种可能的解决方案是使用此批处理代码:

cmd.exe

Windows Management Instrumentation命令的Unicode输出重定向到 FINDSTR ,它过滤以逗号和一位或多位数字结尾的行上的输出。因此,将删除CSV输出的标题行,并删除以@echo off setlocal EnableExtensions DisableDelayedExpansion (for /F "tokens=2-4 delims=," %%I in ('%SystemRoot%\System32\wbem\wmic.exe PATH Win32_VideoController GET Caption^,CurrentHorizontalResolution^,CurrentVerticalResolution /FORMAT:CSV ^| %SystemRoot%\System32\findstr.exe /R ",[0123456789][0123456789]*$"') do ( set /A CurrentVerticalResolution=%%K call echo %%I (%%J x %%CurrentVerticalResolution%%^) ))>"GPU.txt" endlocal 结尾的视频控制器行,其中不包含当前水平和垂直分辨率的值。除了具有正确值的CSV行之外,这种CSV行也将在我的Windows计算机上输出。

尽管使用,,过滤了wmic.exe的输出,但在当前垂直分辨率的最后一个值的末尾仍存在错误的回车问题。

因此,分配给循环变量findstr.exe的当前垂直分辨率值未在K命令行中直接使用,因为这将导致echo覆盖视频控制器字幕字符串的第一个字符。此处使用的解决方案是使用算术表达式将当前的垂直分辨率值分配给环境变量)。算术表达式求值时,整数值末尾的回车符与表达式末尾的任何其他空格字符一样被解释,这意味着CurrentVerticalResolution将忽略它。因此,环境变量cmd.exe分配了该值,而结尾没有不必要的回车。

上面的代码通过使用命令 CALL 来两次解析CurrentVerticalResolution命令行,从而避免使用 SETLOCAL ENDLOCAL ,如下所述通过:

How does the Windows Command Interpreter (CMD.EXE) parse scripts?

在首先解析echo命令行时,已将带有转义的echo和带有)而不是%%CurrentVerticalResolution%%的{​​{1}}命令行修改为下面的行在执行命令 FOR 之前由%CurrentVerticalResolution%进行:

echo

在第二次分析循环中,由于命令 CALL <,在执行第二次解析的命令 ECHO 之前,剩余的环境变量引用cmd.exe被该环境变量的当前值替换。 / strong>。

还可以在 FOR 循环内使用:

call echo %I (%J x %CurrentVerticalResolution%)