views:

265

answers:

2

Related:
How to list the elements of the path in a batch file?
How does FOR work?

How would you write a batch file or CMD file to remove an element from the path? It should handle gracefully:

  • differences in case
  • shortnames and long names

I've done this using tr.exe but it's slow and complicated and uses temporary files, which makes it even more complicated.

I think the answer is something like this:

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

...where %elementToRemove% is the path element to remove. KeepIfUnique would have to be a subroutine that takes two arguments - directory names, normalizes them, and appends the first argument to tpath if it is not equal to the 2nd argument (elementToRemove).

As I said, I can do this with tr.exe, but can I do it with just built-in commands in the windows cmd.exe shell?

EDIT: I guess when you get right down to it, the question is, how to do case-conversion in cmd.exe?

+1  A: 

if command has ignore case option

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

See if /? for more help on using it. I generally found these commands helpful in determining how to do some cmd line trickery:

if /?
call /?
for /?
set /?
Igor Zevaka
+1  A: 

This is what I came up with, using Igor's hint.

@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%
Cheeso