How to search and replace a string in environment

2019-01-19 07:40发布

问题:

Is there any command in batch to search and replace a string in environment variable PATH?

For example the contents of environment variable PATH is:

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

I have to search for C:\Python24 in this variable and need to replace it by C:\Python27.

回答1:

Local PATH replacement

The solution provided by wmz is perfect:

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

For details about replacements in values of environment variables run in a command prompt window set /? or look on the Microsoft pages about

  • Set - Microsoft TechNet page
  • Set - Windows XP product documentation page

On creation of a new process, like the command line interpreter process on running a batch file, Windows creates a copy of the environment variables table of the parent process (Windows Explorer as desktop). Every modification made on the environment variables table are applied only on this copy which avoids impacts on other already running applications. Just applications called from this process get the modified environment variables table (as copy when started as new process).


System PATH replacement

The solution to set or change a variable system wide is the usage of command setx (set extended).

The question How to use setx command in a windows batch file is about same requirement:
How to replace the version of Python in environment variable PATH system wide?

Microsoft wrote on referenced page about command setx:

Setx writes variables to the master environment in the registry. Variables set with setx variables are available in future command windows only, not in the current command window.

This means if Python scripts are executed from same console window after using setx, the local PATH must be also modified using command set. Other instances of environment variable PATH of other console or GUI processes already running on using setx to change the list of directories are not modified by setx. Those processes must be terminated and restarted to take note of changes made on master environment table.

But if the change of the PATH variable should be done system wide and permanently on local computer only and only once, it is often easier to do this via Control Panel - System than doing it with command setx from command line.


Local and system PATH replacement example

Here is an example on how to replace version of Python in local and system environment variable PATH. As an extra feature the path of Python directory is appended if missing in PATH.

@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

Alternate code with delayed expansion:

@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

Please note that PATH is not only an environment variable, but also an internal command. Type in a command prompt window either help path or path /? to get short help for this little command displayed.

The command path is used here to update local instance of environment variable PATH with path %NEWPATH% and to display the directories in local environment variable PATH with last line of the example batch file.

On line with command setx the double quotes around %NEWPATH% are very important as PATH most likely contains also 1 or more directory paths with a space inside. Therefore the entire string which should be assigned to system environment variable PATH must be in double quotes.

But the command path requires the string with the directory paths always without surrounding double quotes even with space characters inside the string simply because this command does not expect or support other options than the list of directory paths (and the developer who wrote the code for command path did most likely not think about removing the double quotes at beginning and end of the string if a user surrounded the string as usual for nearly all other commands with double quotes).

The disadvantages of the batch files above are:

  1. Local PATH contains the directories always with all environment variables already expanded and therefore system PATH does not have anymore for example %SystemRoot% in list of directories.

  2. Additional directories added to local PATH in current command process or any parent process would be also added to system PATH.

A better solution to update system PATH is explained in answer on

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

So a better batch code to replace Python24 by Python27 in local and system PATH is:

@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"
        goto CheckPath
    )
)
echo Error: System environment variable PATH not found.
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.
if not "!SystemPath!" == "!NewPath!" %SystemRoot%\System32\setx.exe PATH "!NewPath!" /M

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

endlocal

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

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