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

时间:2014-07-09 08:04:24

标签: batch-file search replace command

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

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

C:\windows\system32;C:\windows;C:\windows\System32\Wbem;C:\windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\AccuRev\bin;C:\Python24

我必须在此变量中搜索C:\Python24,并需要将其替换为C:\Python27

1 个答案:

答案 0 :(得分:7)

本地路径替换

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

set "PATH=%PATH:Python24=Python27%"

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

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


系统路径替换

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

问题How to use setx command in a windows batch file与要求相同:
如何在系统范围的环境变量 PATH 中替换Python的版本?

Microsoft在引用页面上写了关于命令setx的信息:

  

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

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

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


本地和系统路径替换示例

以下是如何在本地和系统环境变量 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

延迟扩展的备用代码:

@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

请注意 PATH 不仅是环境变量,还是内部命令。在命令提示符窗口中输入help pathpath /?以获取显示的这个小命令的简短帮助。

这里使用命令path来更新环境变量 PATH 的本地实例和path %NEWPATH%,并在本地环境变量 PATH 使用示例批处理文件的最后一行。

与命令setx一致,%NEWPATH%周围的双引号非常重要,因为 PATH 最有可能包含一个或多个内部空间的目录路径。因此,应分配给系统环境变量 PATH 的整个字符串必须是双引号。

但是命令path要求带有目录路径的字符串始终没有包含双引号,即使字符串中包含空格字符也只是因为此命令不期望或支持除目录路径列表之外的其他选项(以及编写命令path的代码的开发人员很可能不考虑在字符串的开头和结尾删除双引号,如果用户像往常一样用双引号括起几乎所有其他命令的字符串)。

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

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

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

  3. 更新系统 PATH 的更好解决方案在

    的答案中有解释

    Why are other folder paths also added to system PATH with SetX and not only the specified folder path?

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

    @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
    

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

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