批处理脚本:尝试回显文件内容时输出为空

Batch scripting: output is empty when trying to echo file content

我正在尝试遍历所有已安装的程序:

wmic /output:C:\temp\InstallList.txt product get name

for /F "tokens=*" %%G in (C:\temp\InstallList.txt) do echo %%G

文件已创建,但输出为空!

输出不为空。输出为 Unicode。使用more转换为当前本地编码。

如果您希望从字符串末尾删除空格,请参见How to remove trailing and leading whitespace for user-provided input in a batch file?

setlocal enabledelayedexpansion
wmic product get name | more >"C:\temp\InstallList.txt"
for /F "skip=1 usebackq tokens=*" %%G in (`type "C:\temp\InstallList.txt"`) do (
    set S=%%G
    set S=!S:~0,-1!
    if "!S!" NEQ "" (echo !S!)
)

可以一次搞定

FOR /F "skip=1 delims=" %%G in ('wmic product get name') do @echo %%G

问题是 wmic 命令输出的 Unicode 格式。因此,您的文件 InstallList.txt 包含许多 0x00 字节,导致 for /F 循环终止。

要解决这个问题,请使用 for /F 循环捕获 wmic 输出,使其转换为 non-Unicode 格式:

@echo off
for /F "skip=1 delims=" %%G in ('
    wmic PRODUCT GET Name
') do echo %%G

skip=1 选项从输出中删除 header Name

不幸的是,输出仍然包含一些令人不安的人工制品(事实上,有一些孤立的 carriage-returns)。要摆脱它们,请嵌套另一个 for /F 循环:

@echo off
for /F "skip=1 delims=" %%G in ('
    wmic PRODUCT GET Name
') do (
    for /F "delims=" %%F in ("%%G") do echo %%F
)

当然你可以用for /F解析你的Unicode输出文件InstallList.txt,但是你不能直接这样做,你需要使用type命令来转换成non-Unicode:

for /F "skip=1 delims=" %%G in ('
    type "C:\temp\InstallList.txt"
') do rem the rest is the same as above

您也可以使用 more 命令来实现,只需编写 more 而不是 type


您可能会注意到 echo 命令返回的每一行都包含尾随空格。如果他们打扰您,您可以使用以下代码:

@echo off
setlocal EnableDelayedExpansion
set "REPL=    "
for /F "skip=1 delims=" %%G in ('
    wmic PRODUCT GET Name
') do (
    for /F "delims=" %%F in ("%%G") do (
        set "LINE=%%F%REPL%"
        set "TRNC=!LINE:*%REPL%=%REPL%!"
        call echo %%LINE:!TRNC!=%%
    )
)
endlocal

我在这里做的是:

  • 在变量 REPL;
  • 中指定一系列空格(在本例中为 4,假设每行在其感兴趣的部分中包含较少的空格)
  • 读取每一行,追加空格序列并将增加的行存储在LINE;
  • 检索每行尾随空格的实际序列(通过在 REPL 中查找序列)并将其存储在 TRNC;
  • 将每行实际的空格顺序替换为空,即截断,然后真正输出剩余的字符串部分;

当然你也可以在解析文件时这样做 InstallList.txt 如上所述。