Windows的%PATH%变量 - 如何在CMD shell中再次分割';'?

10

我刚刚查了一下stackoverflow,它似乎非常有帮助,并且在Windows XP上运行良好。但在使用Windows 7时,出现了一些不明原因的问题。

PATH变量看起来像这样

C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\QuickTime\QTSystem\

很明显,它包含了反斜杠以及我用来将其拆分的分号,在这个包含FOR循环的批处理中:

   FOR /F "delims=;" %%A IN ("%PATH%") DO (
      echo %%A
   )

执行不会引起任何错误,但它只提供一个(第一个)标记。

C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common

我不知道为什么FOR会停止运行,我尝试了几种网上推荐的变化,但都没有解决问题。

非常感谢任何帮助。

Christian


您引用了一个重复的问题,其中包含一个很好的已经被接受且有两个解决方案的答案。jeb的第一个解决方案在大多数情况下都有效,但也可能失败。他的第二个解决方案总是有效的。然而,您选择尝试完全不同的东西。请仔细阅读jeb的解决方案!他使用的是FOR,而不是FOR /F。 - dbenham
2个回答

24

你可以以这种方式做到。

for %%A in ("%path:;=";"%") do (
    echo %%~A
)

(来源)

你的方法存在问题,使用 for /F 开关时,%%A 只指定了第一个标记。你需要这样做:for /f "tokens=1-9 delims=;" %%A in ("%PATH%") 并通过这种方式读取 %%A%%I


问题在于 tokens=1-9 只能获得前几个(9个)路径条目,而我们今天通常有更多的条目。因此,你的主要答案(不带 /F)是最好的选择。 - William
刚找到了这个解决方案。在 Windows 10 上,去掉第二个百分号即可得到以下命令: for %T in ("%path:;=";"%") do (echo %~T) 我还关闭了命令行中的 ECHO 以增加可读性。 - DDay

3

结合从本页和其他stackoverflow页面学到的知识,OP可以扩展为:

如何确保PATH变量具有唯一值?

可以使用数组变量来完成此操作:

REM usage: call :make_path_unique VARNAME "%VARNAME%"
REM 1: splits VARNAME on ';' and builds an array of unique values (case insensitive)
REM 2: glues the array back into a single variable
REM 3: set the VARNAME to this newly unique-ified collection.
REM
REM From: various StackOverflow pages:
REM     https://dev59.com/yW035IYBdhLWcg3wW-pa
REM     https://dev59.com/W3A75IYBdhLWcg3wf5NV
REM     https://dev59.com/E2Up5IYBdhLWcg3w_rrT
REM
:make_path_unique
  setlocal EnableDelayedExpansion
  set VNAME=%~1
  set VPATH=%~2
  set I=0
  for %%A in ("%VPATH:;=";"%") do (
    set FOUND=NO
    for /L %%B in (1,1,!I!) do (
        if /I "%%~A"=="!L[%%B]!" set FOUND=YES
    )
    if NO==!FOUND! (
        set /A I+=1
        set L[!I!]=%%~A
    )
  )
  set FINAL=!L[1]!
  for /L %%n in (2,1,!I!) do (
    set FINAL=!FINAL!;!L[%%n]!
    set L[%%n]=
  )
  for %%P in ("!FINAL!") do (
    endlocal
    set %VNAME%=%%~P
  )
  exit /b 0

步骤摘要:

  1. 使用for循环在“;”处拆分路径并正确处理引号
    1. 使用for循环查看所有先前存储的路径
    2. 仅在添加新路径时扩展数组
  2. 将数组粘合在一起,同时清除数组变量
  3. 替换路径并清除临时变量
  4. 从函数中返回,无错误。

当然,使用以下方式调用:

set PATH=%PATH%;%MY_PATH_ADDITIONS%
call :make_path_unique PATH "%PATH%"

感谢@LotPings的编辑。无大小写比较更好,setlocal/endlocal更清晰。 - Jesse Chisholm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接