CMD shell: PATH 分成几行

CMD shell: PATH splitting onto several lines

我在几个网页上发现了将 Windows %PATH 变量分成多行的不同方法:

1. for /f "delims=;" %a in ("%path%") do echo %a  . . . (doesn't work)
 2. for %G in ("%Path:;=" "%") do @echo %G
 3. for %a in ("%Path:;=";"%") do @echo %~a
 4. ECHO.%PATH:;= & ECHO.%

谁能解释一下why (1) doesn't work, and how (2), (3) and (4) do
而且,有没有办法用 bash-like 变量语义来做到这一点——我的意思是,用 ENABLEDELAYEDEXPANSION ?

1 for /f 遍历一组行。它可以将行拆分为标记,但不能遍历它们

23 - 变量中的每个分号都替换为带引号的定界符(在 2 它是一个 space 并且在 3 中是一个新的分号)和用引号括起来的变量,所以最后我们有

path       dir1;dir2;dir3
quoted    "dir1;dir2;dir3"
replacement
case 2 - "dir1" "dir2" "dir3"
case 3 - "dir1";"dir2";"dir3"
               ^ See here the replacement

然后使用 for 命令遍历带分隔符的(由 space 或分号)的引用元素列表

4 这里用到了解析器。分析行然后执行。在解析时,path 变量中的每个分号都被替换为 & echo.,即一个命令连接和一个新的 echo 命令。所以效果是,当读取该行时,它被处理为

Read line

echo %path:;= &echo.%
     v..............v Variable expanded
      dir1;dir2;dir3 = dir1 & echo.dir2 & echo.dir3

Final command after parser work

echo dir1 &echo.dir2 &echo.dir3
            ^ .........^...  echo commands included in line at parse time

启用延迟扩展后,

1 也不行,它有同样的问题。

23 应该是一样的。唯一的 "problem" 是 setlocal enabledelayedexpansion 对命令行没有影响(您在问题中使用的是什么)。您将需要使用批处理文件或启动一个单独的 cmd 延迟扩展活动

实例
cmd /v /c"for %a in ("!path:;=";"!") do @echo %~a"

唯一的区别是,从批处理文件(而不是命令行)中,解析 @echo %%~a 时,变量中现有的感叹号将丢失。

4 将不起作用。它利用了这样一个事实,即在处理命令行以进行命令处理之前,解析器会进行正常的变量扩展。这样,当分析命令时,可以找到完整的 echo 命令链。

但是使用延迟扩展语法,扩展是在命令被解析后完成的,并且将回显到控制台的是 echo 命令链,而不是它们的执行。