如何在环境变量PATH中搜索和替换字符串?

beg*_*ner 3 search command replace batch-file

是否有批处理命令来搜索和替换环境变量PATH中的字符串?

例如,环境变量PATH的内容是:

C:\windows\system32;C:\windows;C:\windows\System32\Wbem;C:\windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\AccuRev\bin;C:\Python24
Run Code Online (Sandbox Code Playgroud)

我必须C:\Python24在这个变量中搜索并需要替换它C:\Python27.

Mof*_*ofi 8

本地PATH替换

wmz提供的解决方案非常完美:

set "PATH=%PATH:Python24=Python27%"
Run Code Online (Sandbox Code Playgroud)

有关在命令提示符窗口中运行的环境变量值的替换的详细信息,set /?或在Microsoft页面上查看

  • 设置 - Microsoft TechNet页面
  • 设置 - Windows XP产品文档页面

在创建新进程(如运行批处理文件的命令行解释程序)时,Windows会创建父进程的环境变量表的副本(Windows资源管理器作为桌面).对环境变量表进行的每个修改仅应用于此副本,这样可以避免对其他已在运行的应用程序产生影响.只需从此进程调用的应用程序获取已修改的环境变量表(作为新进程启动时为副本).


系统路径替换

设置或更改系统范围变量的解决方案是使用命令setx(set extended).

如何在Windows批处理文件中使用setx命令的问题大致相同:
如何在环境变量PATH系统中替换Python的版本?

Microsoft在有关命令的引用页面上写道setx:

Setx将变量写入注册表中的主环境.使用setx变量设置的变量仅在将来的命令窗口中可用,而不是在当前命令窗口中.

这意味着如果Python脚本在使用后从同一控制台窗口执行setx,则必须使用命令修改本地PATHset.用于更改目录列表的其他控制台或GUI进程的环境变量PATH的其他实例setx不会被修改setx.必须终止并重新启动这些进程,以记录对主环境表所做的更改.

但是,如果PATH变量的更改应该在系统范围内进行,并且仅在本地计算机上进行,并且只能进行一次,通过控制面板 - 系统执行此操作通常比使用setx命令行执行命令更容易.


本地和系统PATH替换示例

以下是如何在本地和系统环境变量PATH中替换Python版本的示例.作为额外功能,如果在PATH中丢失,则附加Python目录的路径.

@echo off

rem Replace Python24 by Python27 in local environment variable PATH.
set "NEWPATH=%PATH:Python24=Python27%"

rem Append C:\Python27 to PATH if not containing C:\Python27 at all.
if "%NEWPATH:Python27=%" == "%PATH%" set "NEWPATH=%PATH%;C:\Python27"

rem Update PATH in system environment table.
%SystemRoot%\System32\setx.exe PATH "%NEWPATH%" /M

rem Update local PATH in this console window. (Important: No double quotes!)
path %NEWPATH%

rem Remove local environment variable NEWPATH as not needed anymore.
set NEWPATH=

rem Output value of local environment variable PATH.
path
Run Code Online (Sandbox Code Playgroud)

具有延迟扩展的备用代码:

@echo off
setlocal EnableDelayedExpansion

rem Replace Python24 by Python27 in local environment variable PATH.
set "NEWPATH=!PATH:Python24=Python27!"

rem Append C:\Python27 to PATH if not containing C:\Python27 at all.
if "!NEWPATH:Python27=!" == "!PATH!" set "NEWPATH=!PATH!;C:\Python27"

rem Update PATH in system environment table.
%SystemRoot%\System32\setx.exe PATH "!NEWPATH!" /M

rem Update local PATH in this console window. (Important: No double quotes!)
endlocal & path %NEWPATH%

rem Output value of local environment variable PATH.
path
Run Code Online (Sandbox Code Playgroud)

请注意,PATH不仅是环境变量,还是内部命令.键入命令提示符窗口help pathpath /?获得显示此小命令的简短帮助.

该命令path在这里用来更新环境变量的本地实例PATHpath %NEWPATH%,并显示在本地环境变量的目录路径与示例批处理文件的最后一行.

在命令行中,setx双引号%NEWPATH%非常重要,因为PATH很可能还包含一个或多个内部空间的目录路径.因此,应分配给系统环境变量PATH的整个字符串必须是双引号.

但该命令path需要与目录路径字符串始终没有周围甚至与字符串中的空格字符的双引号,只是因为该命令不期望或支持超过目录路径列表(和谁写的代码指令开发商的其他选项path做如果用户像往常一样用双引号括起几乎所有其他命令,那么很可能不会考虑在字符串的开头和结尾删除双引号.

上面批处理文件的缺点是:

  1. 本地PATH包含始终具有已扩展的所有环境变量的目录,因此系统PATH不再具有例如%SystemRoot%目录列表中的内容.

  2. 在当前命令进程或任何父进程中添加到本地PATH的其他目录也将添加到系统PATH.

更新系统PATH的更好解决方案将在答案中解释

为什么其他文件夹路径也添加到使用SetX的系统PATH而不仅是指定的文件夹路径?

因此Python24,Python27在本地和系统PATH中替换的更好的批处理代码是:

@echo off
setlocal EnableExtensions EnableDelayedExpansion

rem Define a variable Separator with a semicolon as value if
rem the local PATH string does not end already with a semicolon.
set "Separator="
if not "!PATH:~-1!" == ";" set "Separator=;"

rem Replace Python24 by Python27 in local environment variable PATH.
set "LocalPath=!PATH:Python24=Python27!"

rem Append C:\Python27 to local PATH if not containing C:\Python27 at all.
if "!LocalPath:Python27=!" == "!PATH!" set "LocalPath=!PATH!%Separator%C:\Python27"

rem Update local PATH for this command process in this console window.
endlocal & set "PATH=%LocalPath%"

rem Output value of local environment variable PATH.
path

rem Get system PATH directly from Windows registry to get
rem the directory list with not expanded environment variables.
for /F "skip=2 tokens=1,2*" %%N in ('%SystemRoot%\System32\reg.exe query "HKLM\System\CurrentControlSet\Control\Session Manager\Environment" /v "Path" 2^>nul') do (
    if /I "%%N" == "Path" (
        set "SystemPath=%%P"
        if defined SystemPath goto CheckPath
    )
)
echo Error: System environment variable PATH not found with a non-empty value.
echo/
pause
goto :EOF

:CheckPath
setlocal EnableExtensions EnableDelayedExpansion
rem Define a variable Separator with a semicolon as value if
rem the system PATH string does not end already with a semicolon.
set "Separator="
if not "!SystemPath:~-1!" == ";" set "Separator=;"

rem Replace Python24 by Python27 in system environment variable PATH.
set "NewPath=!SystemPath:Python24=Python27!"

rem Append C:\Python27 to system PATH if not containing C:\Python27 at all.
if "!NewPath:Python27=!" == "!SystemPath!" set "NewPath=!SystemPath!%Separator%C:\Python27"

rem Update system PATH if any change is necessary at all. Command SETX
rem is by default not installed on Windows XP and truncates string values
rem longer than 1024 characters to 1024 characters. So command REG is used
rem to update system PATH in Windows registry if SETX is not available or
rem new system PATH is too long. Administrator privileges are requirend in
rem any case for updating persistent stored system PATH in Windows registry.
if not "!SystemPath!" == "!NewPath!" (
    set "UseSetx=1"
    if not "!NewPath:~1024,1!" == "" set "UseSetx="
    if not exist %SystemRoot%\System32\setx.exe set "UseSetx="
    if defined UseSetx (
        %SystemRoot%\System32\setx.exe Path "!NewPath!" /M >nul
    ) else (
        set "ValueType=REG_EXPAND_SZ"
        if "!NewPath:%%=!" == "!NewPath!" set "ValueType=REG_SZ"
        %SystemRoot%\System32\reg.exe ADD "HKLM\System\CurrentControlSet\Control\Session Manager\Environment" /f /v Path /t !ValueType! /d "!NewPath!" >nul
    )
)

rem Output value of system environment variable PATH.
echo PATH=!NewPath!

endlocal
Run Code Online (Sandbox Code Playgroud)

要了解使用的命令及其工作方式,请打开命令提示符窗口,执行以下命令,并完全阅读为每个命令显示的所有帮助页面.

  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • if /?
  • path /?
  • pause /?
  • rem /?
  • reg add /?
  • reg query /?
  • set /?
  • setlocal /?