Удалите нежелательный путь из переменной%path% через пакет

Область применения: Windows XP или новее. Инструменты: пакетный скрипт.

Мне нужно иметь возможность удалить ненужный путь из системной переменной%PATH%. Я знаю, как добавить новое имя пути в системную переменную%PATH%, используя такой инструмент, как SETX.EXE, который также сразу делает его доступным в существующей среде CMD. Вероятно, дело в том, чтобы использовать какой-то цикл FIND и / или цикл FOR, но я не совсем уверен, как этого добиться. Вот пример утверждения пути...

%PATH% = C:\;C:\Program Files\Common Files\Java;C:\oracle\product\10.2.0\bin;C:\WINDOWS;C:\WINDOWS\system32;

Из этого мне нужно иметь возможность удалить полный путь, связанный с "оракулом". Итак, в приведенном выше примере мне нужно иметь возможность удалить "C:\oracle\product\10.2.0\bin" из приведенного выше оператора пути. К сожалению, имя оракула может не только отличаться от указанного выше, но также может быть несколько имен путей оракула, и все они должны быть удалены. Я попытался реализовать решение здесь...

Как извлечь полный путь из переменной среды PATH?

Тем не менее, это просто не работает. Сценарий не может найти имя пути. Любая помощь будет оценена. Спасибо.

8 ответов

Это удаляет подстроку C:\Program Files (x86)\Git\bin; из строки PATH и переназначает:

set PATH=%PATH:C:\Program Files (x86)\Git\bin;=%

Вы можете использовать это, чтобы увидеть изменения:

echo %PATH:C:\Program Files (x86)\Git\bin;=% | tr ; \n

Примечание: быть точным на подстроке. Это регистр и слэш.

Если вам нужно сделать это постоянное изменение, используйте setx вместо set и откройте другую консоль, чтобы изменения вступили в силу.

setx /M PATH "%PATH:C:\Program Files (x86)\Git\bin;=%"

Вы можете попробовать что-то вроде этого:

@echo off&cls
setlocal EnableDelayedExpansion
set $line=%path%
set $line=%$line: =#%
set $line=%$line:;= %

for %%a in (%$line%) do echo %%a | find /i "oracle" || set $newpath=!$newpath!;%%a
set $newpath=!$newpath:#= !
echo set path=!$newpath:~1!

Я положил echo до последней строки. Проверьте результат и, если он в порядке, удалите его.

@SachaDee Я получил ошибки с путями, такими как

C:\Program Files (x86)

с кронштейнами: Program Files (x86)\Directoryдал мне

каталогwas unexpected at this time. (независимо от того, во сколько я попробовал это)

я добавил

set $line=%$line:)=^^)%

перед циклом и

set $newpath=!$newpath:^^=!

после цикла (не уверен, если это необходимо)

@echo off
setlocal EnableDelayedExpansion
set path
set $line=%path%
set $line=%$line: =#%
set $line=%$line:;= %
set $line=%$line:)=^^)%

for %%a in (%$line%) do echo %%a | find /i "oracle" || set $newpath=!$newpath!;%%a
set $newpath=!$newpath:#= !
set $newpath=!$newpath:^^=!
set path=!$newpath:~1!

Я нашел другие решения этой проблемы немного неловкими, я действительно не хочу полагаться на точные пути, сложный синтаксис "отложенного расширения", удаляя пробелы для цикла "for /f", а затем добавляя их обратно в...

Я думаю, что это более изящно, и я прокомментировал, черт возьми, так, что даже кто-то новичок в ужасах Batch может следовать.

::Turn off command display and allows environmental variables to be overridden for the current session
@echo off & setlocal

::Creates a unique file to use for the 'for loop'
set "TMPFILE="%temp%\tmp%RANDOM%%RANDOM%.txt""

::Duplicate PATH into OLDPATH
set "OLDPATH=%PATH%"

::Declare label for the 'goto' command
:Loop

::Extract the first text token with the default delimiter of semicolon
for /f "tokens=1 delims=;" %%G in ("%OLDPATH%") do (

REM Copy text token to TMPFILE unless what we want to remove is found
<NUL set /p="%%G" | find /i "StRiNgThAtMaTcHeSwHaTtOrEmOvE" >NUL 2>&1 || <NUL set /p="%%G;" >>%TMPFILE%

REM Remove text token from OLDPATH
set "OLDPATH=%OLDPATH:*;=%"
)

::Repeat loop until OLDPATH no longer has any delimiters, and then add any remaining value to TMPFILE
echo %OLDPATH% | findstr /C:";" >NUL && (goto :Loop) || <NUL set /p="%OLDPATH%" >>%TMPFILE%

::Set the path to TMPFILE
for /f "usebackq delims=" %%G in (%TMPFILE%) do (set "PATH=%%G")

::Clean-up
del %TMPFILE% >NUL 2>&1

::An echo and pause just for debug purposes
echo %PATH%
pause

Если вы знаете файл, который существует в каталоге, который вы хотите удалить (например, хотите удалить все пути, которые могут включать java.exe), следующее будет работать очень просто, просто выполняя замену строки, не нужно анализировать путь и т. д.:

      @REM Executable to look for
set CMD=java.exe

:search
@REM Find the executable anywhere in the path
for %%a in (%CMD%) do set FOUND=%%~$PATH:a
if "%FOUND%"=="" goto done

@REM Strip \cmd.ext so we just have the directory
set FOUND=!FOUND:\%CMD%=!
@echo Found %CMD% in %FOUND%

@echo Removing %FOUND% from path...
set "PATH=!PATH:%FOUND%=!"

@REM Clean up any lone leftover \ in the path (in case the path was C:\foo\ instead of C:\foo)
set PATH=%PATH:;\;=;%

goto search
:done

Хотел убрать из. Но это было невозможно из-за использования другой переменной в переменной среды для Windows. В CALLхак работает в SS64 . (Также спасибо Jens A. Koch за команду базы.)

      CALL set PATH=%PATH:%LocalAppData%\Microsoft\WindowsApps;=%

Конечно, изменение не будет постоянным. Для фиксированного изменения необходимо использовать SETX или напрямую изменить записи в реестре.

Собственно, это решение не нужно было удалять из.

В %LocalAppData%\Microsoft\WindowsApps; хранится в PATH запись в Реестре HKCU\Environmentключ. Хотя более практично удалить эту запись с помощью REG DELETE команда, если в записи PATH есть другие каталоги, они также будут удалены, поэтому необходимо новое решение.

Мне не удалось удалить %USERPROFILE% синтаксис переменных из SET%%символ дилеммы). К счастью, на помощь пришел PShell:

SET userprofile= Powershell -c "$UserEnvironmentPath = [System.Environment]::GetEnvironmentVariable('Path', 'User'); $UserEnvironmentPath = $UserEnvironmentPath.Replace('%USERPROFILE%\AppData\Local\Microsoft\WindowsApps;',''); [Microsoft.Win32.Registry]::SetValue('HKEY_CURRENT_USER\Environment', 'Path', $UserEnvironmentPath, [Microsoft.Win32.RegistryValueKind]::ExpandString)"

Отдельное спасибо vonPryz за последнюю команду . Поскольку PowerShell [System.Environment]::SetEnvironmentVariable команда сохраняет переменные в реестр как REG_SZ даже если их исходный тип значения REG_EXPAND_SZ, а это известная проблема.

Я использую это в CYGWIN, чтобы отфильтровать пути CYGWIN перед запуском некоторых команд Windows:

      export PATH=`perl -e '@a=grep {$_ =~ /^\/cygdrive\//} split(":", $ENV{PATH});print join(":",@a)'`

Я совершенно уверен, что это легко адаптировать к файлам perl и bat для Windows. Преимущество: гибкие возможности регулярных выражений.

Я написал этот код, чтобы просто удалить любой исполняемый путь python из переменной пути и вставить свою собственную версию python в путь, чтобы я мог запускать python с нужной версией.

      setlocal enableDelayedExpansion 
set path`enter code here`
set $line=%path%
set $line=%$line: =#%
set $line=%$line:;= %
set $line=%$line:)=^^)%
set newpath=
for %%a in (%$line%)  do (
   echo %%a | find /i "python" ||set newpath=!newpath!;%%a
)
set path=!newpath!
set PATH=D:\python2.7\;%PATH%
@REM Rest of your script

python --version

@REM to exit the batch but not the window
exit /b

также важна первая строка! не удаляйте его, иначе он не сработает.

Примечание: этот код должен запускаться из пакетного файла «.bat», если вы хотите скопировать и вставить этот код в окно cmd, вы должны заменить все «%%a» на «%a» в этом коде.

Другие вопросы по тегам