Batch For Loop 将 Space 描述的输入视为单个标记

Batch For Loop Treating Space-delineated Input as Single Token

我正在编写一个批处理脚本,它可以提示用户输入项目列表,然后依次处理每个项目。我的想法是这可以通过 for 循环来完成,但它不起作用。出于某种原因,它将用户输入的整个字符串 (CanalyzerIF CanoeIF CometIF) 视为单个标记。

echo Enter the names of the projects, deliniating each with a space:
set /P PROJECT_LIST=
echo.
echo DEBUG: PROJECT_LIST is %PROJECT_LIST%
echo These are the projects you specified:
for /F "tokens=*" %%i in ("%PROJECT_LIST%") do (
  echo   %%i
)

我的脚本输出如下所示...

DEBUG: PROJECT_LIST is CanalyzerIF CanoeIF CometIF
These are the projects you specified:
  CanalyzerIF CanoeIF CometIF

...当我 expect/want 看到的是:

DEBUG: PROJECT_LIST is CanalyzerIF CanoeIF CometIF
These are the projects you specified:
  CanalyzerIF
  CanoeIF
  CometIF

我用百分号(%)或者感叹号(!)把PROJECT_LIST包起来好像都没有关系。有人知道如何解决这个问题吗?

try with (plain FOR 可用于迭代):

echo Enter the names of the projects, deliniating each with a space:
set /P "PROJECT_LIST="
echo.
echo DEBUG: PROJECT_LIST is %PROJECT_LIST%
echo These are the projects you specified:
for   %%i in (%PROJECT_LIST%) do (
  echo   %%i
)

除了@npocmaka完美解决使用for不使用/F的问题,我想提供一个使用/F选项的解决方案,主要是为了演示。

首先让我们看一下没有选项字符串的for /F,所以使用默认选项,就像"tokens=1 delims= _"_在这里代表一个制表符)。这意味着获取第一个 space- 或制表符分隔的标记并将其分配给给定变量,如 %%i(即列表中的第一个项目)并忽略其余部分。
要获取多个项目,您需要准确指定要提取的项目。例如,要获得令牌 2、3、4 和 6,状态 "tokens=2-4,6".
这些标记中的第一个分配给给定变量 %%i,其他分配给 %%j%%k%%l(构成隐式定义的变量)。
特殊标记 * 表示将 所有 剩余标记传递给单个变量,或者换句话说,将它们视为单个标记(例如, "tokens=1,*" 将第一个令牌传递给 %%i,将其余所有令牌传递给 %%j)。

理解所有这些会导致我们使用 for /F 的主要问题:您需要知道有多少令牌可用。但是对于这个应用,我们不知道。

以下使用选项字符串 "tokens=1,*" 提取第一个标记和所有其余标记;有一种 while 循环环绕(由 ifgoto 组成)旨在重新处理所有其余部分,直到没有任何可用的为止(这里我明确定义了 space成为唯一可接受的分隔符):

echo Enter the names of the projects, deliniating each with a space:
set /P PROJECT_LIST=
echo.
echo DEBUG: PROJECT_LIST is %PROJECT_LIST%
echo These are the projects you specified:
set PROJECT_TEMP=%PROJECT_LIST%
:LOOP
if not defined PROJECT_TEMP goto :NEXT
for /F "tokens=1,* delims= " %%i in ("%PROJECT_TEMP%") do (
  echo.  %%i
  set PROJECT_TEMP=%%j
)
goto :LOOP
:NEXT

所以原始代码中的主要问题是选项字符串"tokens=*",它定义将所有个令牌传递给变量%%i

键入 for /? 以获取有关所有这些的更多详细信息。