为什么此批处理脚本中的FOR/f循环评估空行?

Mor*_*nar 8 batch-file

我正在尝试编写一个批处理脚本,该脚本可以获取(除其他外)计算机所有磁盘驱动器的列表.基本代码看起来像这样:

REM Build the list of disk drives to monitor
SETLOCAL enabledelayedexpansion
FOR /f "skip=1 tokens=1 delims=:" %%a in ('"WMIC logicaldisk WHERE drivetype=3 GET deviceid"') do (
    SET "DISK_DATABASES=!DISK_DATABASES!%%a|"
    SET "DRIVES_TO_MONITOR=!DRIVES_TO_MONITOR!%%a:\\|"
)
Run Code Online (Sandbox Code Playgroud)

我显然构建了两个格式略有不同的列表供以后使用.然而,当我运行它时,我得到的输出看起来像这样:

C|D|E||
C:\\|D:\\|E:\\|:\\|
Run Code Online (Sandbox Code Playgroud)

现在,我希望两种情况下的尾随管道都可以管理,但我真的很困惑,为什么还有一个额外的空白条目.如果我wmic手动运行命令,我可以看到输出结尾确实有一个空行,但我的理解是/f特别应该忽略空行.

如果我打开ECHO,看起来最后一行只是作为回车/换行符或类似物进入.有没有办法做我期待的事情?我错过了什么吗?我试图if在循环中写一个条件来排除最后一行,但它是......时髦而且从未奏效.我感谢任何/所有的帮助.

dmi*_*try 11

我刚刚谈到这个话题.我一直在使用findstr/v来排除空行:

FOR /f "usebackq skip=1 tokens=1 delims=:" %%a in (`WMIC logicaldisk WHERE "drivetype=3" GET deviceid ^| findstr /v /r "^$"`) do (
Run Code Online (Sandbox Code Playgroud)


jeb*_*jeb 5

在这种情况下,最后一次迭代不会产生一个空项,并且C|D|E||只得到你的输出echo %DISK_DATABASES%,
但是echo !DISK_DATABASES!会输出||D|E|

那是因为最后一个元素是单个 <CR>字符.
并且<CR>在扩展百分比之后直接删除字符,但不会延迟扩展.

你可以避免这种情况,使用百分比扩展来删除它们

setlocal EnableDelayedExpansion
FOR /f "skip=1 tokens=1 delims=:" %%a in ('"WMIC logicaldisk WHERE drivetype=3 GET deviceid"') do (
  set "item=%%a"
  call :removeCR

  if not "!item!"=="" (
    SET "DISK_DATABASES=!DISK_DATABASES!!item!|"
    SET "DRIVES_TO_MONITOR=!DRIVES_TO_MONITOR!!item!:\\|"
  )
)
goto :eof
:removeCR

:removeCR
set "Item=%Item%"
exit /b
Run Code Online (Sandbox Code Playgroud)