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
遍历一组行。它可以将行拆分为标记,但不能遍历它们
2 和 3 - 变量中的每个分号都替换为带引号的定界符(在 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 也不行,它有同样的问题。
2 和 3 应该是一样的。唯一的 "problem" 是 setlocal enabledelayedexpansion
对命令行没有影响(您在问题中使用的是什么)。您将需要使用批处理文件或启动一个单独的 cmd
延迟扩展活动
实例
cmd /v /c"for %a in ("!path:;=";"!") do @echo %~a"
唯一的区别是,从批处理文件(而不是命令行)中,解析 @echo %%~a
时,变量中现有的感叹号将丢失。
4 将不起作用。它利用了这样一个事实,即在处理命令行以进行命令处理之前,解析器会进行正常的变量扩展。这样,当分析命令时,可以找到完整的 echo
命令链。
但是使用延迟扩展语法,扩展是在命令被解析后完成的,并且将回显到控制台的是 echo
命令链,而不是它们的执行。
我在几个网页上发现了将 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
遍历一组行。它可以将行拆分为标记,但不能遍历它们
2 和 3 - 变量中的每个分号都替换为带引号的定界符(在 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 也不行,它有同样的问题。
2 和 3 应该是一样的。唯一的 "problem" 是 setlocal enabledelayedexpansion
对命令行没有影响(您在问题中使用的是什么)。您将需要使用批处理文件或启动一个单独的 cmd
延迟扩展活动
cmd /v /c"for %a in ("!path:;=";"!") do @echo %~a"
唯一的区别是,从批处理文件(而不是命令行)中,解析 @echo %%~a
时,变量中现有的感叹号将丢失。
4 将不起作用。它利用了这样一个事实,即在处理命令行以进行命令处理之前,解析器会进行正常的变量扩展。这样,当分析命令时,可以找到完整的 echo
命令链。
但是使用延迟扩展语法,扩展是在命令被解析后完成的,并且将回显到控制台的是 echo
命令链,而不是它们的执行。