【问题标题】:Skipping last empty line of WMIC command output in batch批量跳过 WMIC 命令输出的最后一个空行
【发布时间】:2016-06-08 15:11:51
【问题描述】:

我正在尝试将 JSON 中的命令输出格式化为:

echo "patches" : {
set patches="wmic qfe get HotfixID"
for /f "skip=1" %%i in (' %patches% ') do (
    set /a count=count+1
    call echo "!count!" : "%%i",
)
echo }

一切都很好,直到我到达补丁列表的末尾,它读取最后一个补丁之后的行,然后打印""

我怎样才能让它在它应该停止的时候停止?

如果可能,我想避免使用文本文件。

【问题讨论】:

  • for /f 循环中,放置另一个for /f "delims=" %%j in ("%%i") do 并在您的echo 中使用%%j;因为 wmic 返回 Unicode 输出,而 for /f 不适合处理它,for /f 输出像孤立的回车这样的伪影,导致你遇到的效果;在内部放置另一个 for /f 循环,因此对每个项目进行双重处理会删除此类伪像...
  • 有一个bunch of different methods 可以绕过那些wmic 行尾。虽然我认为,第二个for 是其中最通用的。
  • 是的,@Stephan,但是 double-for /f-loop 方法是最简单、最安全的方法,因为它可以处理具有任何特殊字符序列的字符串...(我知道您可以查询另一个项目并稍后将其关闭,这同样安全,但这不是通用的,因为它仅适用于/TABLE 输出,但不适用于/VALUE 输出...)

标签: batch-file cmd output


【解决方案1】:

for /f 循环内,放置另一个:

for /f "skip=1" %%i in ('%patches%') do for /f "delims=" %%j in ("%%i") do (
    rem // use `%%j` in the loop body
)

wmic 命令返回 Unicode 输出。由于for /f 不适合处理此类问题,它会产生像孤立的回车符 (CR) 这样的伪影,从而导致您遇到的效果(最后一行在您的 for /f %%i 循环中不会显示为空,因为它包含这样的 CR;请记住for /f 会跳过真正空的行)。在内部放置另一个 for /f 循环,因此对每个项目进行双重处理会删除此类伪影。

这里是固定脚本:

echo "patches" : {
set "patches=wmic qfe get HotfixID"
for /f "skip=1" %%i in ('%patches%') do for /f "delims=" %%j in ("%%i") do (
    set /a count=count+1
    echo "!count!" : "%%j",
)
echo }

由于我没有得到call 命令的用途,所以我将其删除。


双重解析方法其实归功于dbenham——见他对Why is the FOR /f loop in this batch script evaluating a blank line?的回答以及他的外部文章WMIC and FOR /F : A fix for the trailing <CR> problem

【讨论】:

    【解决方案2】:

    批量跳过WMIC命令输出的最后一个空行

    最简单的解决方案是使用findstr 删除空行:

    for /f "skip=1" %%i in ('%patches% ^| findstr /r /v "^$"')
    

    不需要额外的for 循环。


    进一步阅读

    【讨论】:

    • 这么长时间被忽视的杰作
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多