Как бы вы написали файл .bat или .cmd, чтобы удалить элемент из PATH?

Связано:
Как составить список элементов пути в пакетном файле?
Как работает FOR?

Как бы вы написали пакетный файл или файл CMD, чтобы удалить элемент из пути? Он должен работать изящно:

  • различия в случае
  • короткие имена и длинные имена

Я сделал это с помощью tr.exe, но это медленно и сложно и использует временные файлы, что делает его еще более сложным.

Я думаю, что ответ примерно такой:

setlocal
set tpath="" 
set _path="%PATH:;=" "%"
for %%p in (%_path%) do (
   call :KeepIfNotEqual %%p %elementToRemove% 
)
endlocal & set path=%tpath%

... где %elementToRemove% — это удаляемый элемент пути. KeepIfUnique должна быть подпрограммой, которая принимает два аргумента — имена каталогов, нормализует их и добавляет первый аргумент к tpath, если он не равен второму аргументу (elementToRemove).

Как я уже сказал, я могу сделать это с помощью tr.exe, но могу ли я сделать это только с помощью встроенных команд в оболочке Windows cmd.exe?

EDIT: я думаю, когда вы приступите к делу, вопрос в том, как сделать преобразование регистра в cmd.exe?


person Cheeso    schedule 15.09.2009    source источник
comment
Windows 7 включает в себя PowerShell 2, который, мы надеемся, сделает вашу жизнь намного проще...   -  person TrueWill    schedule 16.09.2009


Ответы (3)


Вот что я придумал, воспользовавшись подсказкой Игоря.

@echo off
goto START

-------------------------------------------------------
 rmpath.bat

 remove a path element from path 

 Created Tue Sep 15 21:33:54 2009 

-------------------------------------------------------

:START
SETLOCAL ENABLEDELAYEDEXPANSION 

@REM require one argument (the path element to remove)
if  _%1==_ goto USAGE

@REM  ~fs = remove quotes, full path, short names
set fqElement=%~fs1

@REM convert path to a list of quote-delimited strings, separated by spaces
set fpath="%PATH:;=" "%"

@REM iterate through those path elements
for %%p in (%fpath%) do (
    @REM  ~fs = remove quotes, full path, short names
    set p2=%%~fsp
    @REM is this element NOT the one we want to remove?
    if /i NOT "!p2!"=="%fqElement%" (
        if _!tpath!==_ (set tpath=%%~p) else (set tpath=!tpath!;%%~p)
    )
)

set path=!tpath!

@call :LISTPATH

goto ALL_DONE
-------------------------------------------------------

--------------------------------------------
:LISTPATH
  echo.
  set _path="%PATH:;=" "%"
  for %%p in (%_path%) do if not "%%~p"=="" echo     %%~p
  echo.
  goto :EOF
--------------------------------------------


--------------------------------------------
:USAGE
  echo usage:   rmpath ^<arg^>
  echo     removes a path element from the path.
  goto ALL_DONE

--------------------------------------------

:ALL_DONE
ENDLOCAL & set path=%tpath%
person Cheeso    schedule 16.09.2009
comment
Отличное решение. Этот параметр нужно указывать в кавычках? И удаляет ли это ВСЕ записи из пути или только первую? - person Richard Duerr; 13.11.2015

Команда if имеет опцию игнорирования регистра

if /I "Blah"=="blah" (echo true) else (echo false)

См. if /? для получения дополнительной помощи по его использованию. Обычно я нахожу эти команды полезными для определения того, как выполнить некоторые трюки с командной строкой:

if /?
call /?
for /?
set /?
person Igor Zevaka    schedule 16.09.2009
comment
Хотя я понимаю, что вы не хотите кормить людей ответами с ложечки, этот вопрос не совсем прост и имеет много движущихся частей. Это общая проблема, которую необходимо решить. - person Richard Duerr; 13.11.2015

Я хочу добавить кое-что к ответу Cheeso... но у меня недостаточно представителей, чтобы добавить комментарий.

Если вы хотите, чтобы предоставленный им сценарий работал даже после завершения пакетного файла, измените последнюю строку следующим образом:

@echo off
  . . .
  . . .
SETLOCAL ENABLEDELAYEDEXPANSION
  . . .
  . . .
endlocal & set path=%tpath%

Здесь используется хитрый трюк: переменная tpath доступна, когда эта строка считывается и анализируется cmd.exe и расширяется перед тем, как быть удаленной endlocal. .

Это позволяет сохранять изменения в переменной PATH даже после выхода из командного файла.

person CrashNeb    schedule 17.03.2016