'漂亮打印'窗口%PATH%变量 - 如何拆分';' 在CMD shell中

sam*_*sam 47 windows path batch-file

我想在Windows CMD提示符中运行一个简单的单行程序来打印我的%PATH%变量,每行一个条目.

我试过这个:for /f "delims=;" %a in ("%path%") do echo %a但这只打印第一个条目:

Z:\>for /f "delims=;" %a in ("%path%") do echo %a

Z:\>echo c:\python25\.
c:\python25\.
Run Code Online (Sandbox Code Playgroud)

另外从上面的输出中可以看出,这也是打印echo %a命令和输出.有没有办法阻止这个?

如果我尝试一个类似的命令,我会得到所有条目,但仍然得到echo %a输出垃圾邮件的结果.我不明白为什么以下打印所有条目,但我的尝试%PATH%没有.我怀疑我不懂/F开关.

Z:\>for %a in (1 2 3) do echo %a

Z:\>echo 1
1

Z:\>echo 2
2

Z:\>echo 3
3
Run Code Online (Sandbox Code Playgroud)

jeb*_*jeb 68

简单的方法是使用

for %a in ("%path:;=";"%") do @echo %~a
Run Code Online (Sandbox Code Playgroud)

这适用于没有;在路径中的所有人,没有"围绕单个元素
测试路径= C:\ qt\4.6.3\bin; C:\ Program Files; C:\ documents&Settings

但是"始终"的解决方案有点复杂
EDIT:现在是一个有效的变体

@echo off
setlocal DisableDelayedExpansion
set "var=foo & bar;baz<>gak;"semi;colons;^&embedded";foo again!;throw (in) some (parentheses);"unmatched ;-)";(too"

set "var=%var:"=""%"
set "var=%var:^=^^%"
set "var=%var:&=^&%"
set "var=%var:|=^|%"
set "var=%var:<=^<%"
set "var=%var:>=^>%"

set "var=%var:;=^;^;%"
rem ** This is the key line, the missing quote is intended
set var=%var:""="%
set "var=%var:"=""%"

set "var=%var:;;="";""%"
set "var=%var:^;^;=;%"
set "var=%var:""="%"
set "var=%var:"=""%"
set "var=%var:"";""=";"%"
set "var=%var:"""="%"

setlocal EnableDelayedExpansion
for %%a in ("!var!") do (
    endlocal
    echo %%~a
    setlocal EnableDelayedExpansion
)
Run Code Online (Sandbox Code Playgroud)

那我在那做什么?
我试图解决主要问题:引号内的分号应该被忽略,只有正常的分号应该被替换为";"

我使用批量解释器本身来解决这个问题.

  • 首先,我必须使字符串安全,逃避所有特殊字符.
  • 然后全部;被替换^;^;
  • 然后技巧从线开始
    set var=%var:"=""%"(缺少的引用是关键!).
    这扩展的方式使得所有转义字符都将丢失它们的转义符号:
    var=foo & bar;;baz<>gak;;"semi^;^;colons^;^;^&embedded";;foo again!;;...
    但仅在引号之外,所以现在引号;;和内部之间的分号之间存在差异^;^;.
    这是关键.

  • @bobbogo:NTFS文件名中唯一无效的字符是`/`和`\ 0`.用户域Windows API进一步限制,但仅包括用于shell的字符(`<>&|*?"\`). (3认同)

Ste*_*uan 66

一个简单的衬垫,可以打印PATH环境变量:

ECHO.%PATH:;= & ECHO.%
Run Code Online (Sandbox Code Playgroud)

如果你的PATH等于A;B;C上面的字符串替换将改变ECHO.A & ECHO.B & ECHO.C它并一次性执行它.完全停止可防止出现"ECHO is on"消息.

  • 在“cmd”中对我来说效果很好,但在 PowerShell 中失败 (2认同)

小智 10

对Stephan Quan非常聪明的单线解决方案的更新:我遇到的问题是尾随的分号 - (可能是两个连续的分号,即空路径元素)会导致出现"ECHO is on"消息.我通过在第二个ECHO语句之后插入一个句点来解决这个问题(这是抑制ECHO开启/关闭消息的语法).但是,它会导致额外的空行:

ECHO %PATH:;= & ECHO.%
Run Code Online (Sandbox Code Playgroud)


dbe*_*ham 9

我对jeb聪明的"永远"解决方案进行了一些小的改进.目前jeb的解决方案存在以下问题:

  1. 如果前导路径用引号括起来,那么第一个输出以""开头
  2. 如果尾随路径用引号括起来,那么最后一个输出以""结尾
  3. 如果任何路径包含无害但无功能的连续"",则输出保留""
  4. 如果var包含连续的;; 然后分隔符输出ECHO关闭

此解决方案解决了小问题,而且它使用了2个更少的替换.我还消除了循环中不必要的重复启用/禁用延迟扩展.(编辑于2011-10-30简化了ENDLOCAL逻辑)

@echo off
setlocal DisableDelayedExpansion
set "var=%var:"=""%"
set "var=%var:^=^^%"
set "var=%var:&=^&%"
set "var=%var:|=^|%"
set "var=%var:<=^<%"
set "var=%var:>=^>%"
set "var=%var:;=^;^;%"
set var=%var:""="%
set "var=%var:"=""Q%"
set "var=%var:;;="S"S%"
set "var=%var:^;^;=;%"
set "var=%var:""="%"
setlocal EnableDelayedExpansion
set "var=!var:"Q=!"
for %%a in ("!var:"S"S=";"!") do (
  if "!!"=="" endlocal
  if %%a neq "" echo %%~a
)
Run Code Online (Sandbox Code Playgroud)

如果你想看到连续的每个空路径都有一个空行;; 分隔符,然后FOR循环的最后一行可以简单地读取echo(%%~a.

或者使用以下方式将空路径显示为""可能更为明显:
if %%a=="" (echo "") else echo %%~a

各种空路径修复也适用于jeb的简单解决方案.


更新:这是一个简单的单行使用JREPL.BAT

您可以使用我的JREPL.BAT正则表达式文本处理实用程序来实现简单,非常强大的解决方案.JREPL.BAT是纯脚本(混合JScript /批处理),可以在XP之后的任何Windows机器上本机运行.

jrepl "([^;\q]+|\q.*?(\q|$))+" $0 /x /jmatch /s path
Run Code Online (Sandbox Code Playgroud)