为什么在这个批处理脚本的FOR / F闭环评估一个空行?

问题描述:

我试图写一个批处理脚本获得(除其他事项外)所有磁盘的驱动器列表的计算机。基本的code看起来是这样的:

I'm trying to write a batch script that obtains (among other things) a list of all of the disk drives the computer has. The basic code looks something like this:

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:\\|"
)

我pretty显然构建略有不同的格式,以备后用两个列表。当我运行这一点,但是,输出我得到类似如下:

I pretty obviously build two lists with slightly different formats for use later. When I run this, however, the output I get looks something like this:

C|D|E||
C:\\|D:\\|E:\\|:\\|

现在,我希望在这两种情况下尾随管,我可以管理,但我真的很困惑,为什么没有在有一个额外的空白项。如果我手动运行 WMIC 命令,我可以看到,确实是有在输出的最后一个空行,但我的理解是, / ˚F专门应该忽略空白行。

Now, I expect the trailing pipe in both cases and I can manage that, but I'm really confused why there is an extra blank entry in there. If I run the wmic command manually, I can see that there is indeed a blank line at the end of the output, but my understanding is that /f was specifically supposed to ignore blank lines.

如果我把 ECHO 上,它看起来像最后一行是刚进来的是一个回车/换行或相似。有没有办法做我期待?我缺少的东西吗?我试图在循环排除最后一行写的如果的条件,但它是...时髦且从来没有工作过。我AP preciate任何/所有帮助。

If I turn ECHO on, it looks like that last line is just coming in as a carriage return/newline or similar. Is there a way to do what I'm expecting? Am I missing something? I tried to write an if condition in the loop to exclude this last line, but it was... funky and never worked. I appreciate any/all help.

在这种情况下,最后一次迭代产生的不是空洞的项目,你会得到你的的C输出| D |电子|| 回声%DISK_DATABASES%,结果
回声DISK_DATABASES 将输出 ||开发|!E | ??

In this case the last iteration produces not an empty item, and you get your output of C|D|E|| only with echo %DISK_DATABASES%,
but echo !DISK_DATABASES! will output ||D|E|??

这是因为最后一个元素是一个< CR方式> 字符结果
< CR> 字符直接的百分比扩建后删除,但不会延迟扩展。

That's because the last element is a single <CR> character.
And <CR> characters are directly removed after the percent expansion, but not with delayed expansion.

您可能避免这一点,使用百分比扩张删除它们。

You could avoid this, using the percent expansion to remove them

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