Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!

Remove a semicolon-separated directory from the path

Aug
1,916
68
On occasion, I have programs in my path that conflict with other programs that I am wanting to use.

For example, the hbmk2.exe program in c:\hb32\bin has it's own version of the MinGW compilers, while I use the MinGW compiler in C:\MinGW for other development applications.

There are also times when the Gtk toolkit and assorted GNOME libraries causes problems when doing .NET development vs. Mono development.

I can use the eset command to edit the path, but I have developed a .BTM to make it easier.

This is by no means a finished, or polished .BTM, but it does what I need it to do.

I am sure that many lines could be eliminated by the use of TPipe, and if you are so inclined, please feel free to show how easy the same thing can be accomplished with TPipe, as I would also like to know.

Anyway, here is my non-TPipe solution;
Code:
:: PATHMAN.BTM
:: Removes a semicolon-separated directory from the path.
::
:: Similar to what the PATHMAN.EXE utility does,
::  which is part of the Windows Server 2003 Resource Kit,
::  which does not work on Windows Vista.
::
:: TCC  16.03.54  Windows Vista [Version 6.0.6002]
:: TCC Build 54  Windows Vista Build 6002  Service Pack 2
:: Joe Caverly
::
@setlocal
@echo off
::
:: How many Semi-Colons are in the path?
::
set SColons=%@count[;,%path]
set SColons=%@inc[%SColons]
::
:: pathlist is an alias
:: Ref: http://jpsoft.com/forums/threads/pathlist-alias.5138/
::
If not IsAlias pathlist alias pathlist=`echo %=n %@replace[;,%=n ,%path]`
::
:: Read the path into an array
::
set pathlist=%@unique[]
pathlist > %pathlist
setarray /r %pathlist aPath
::
:: Display a list of the directories in the path
::
do kount=0 to %SColons
  if %@len[%aPath[%kount]] gt 0 echo %aPath[%kount]
enddo
::
:: Ask the user what directory they want removed from the path
::
echo %@select[%pathlist,0,0,%_rows,%_columns,Select an option] > nul
set theline=%@dec[%SELECT_LINE]
::
:: If the Esc key was pressed...
::
iff %theline eq -1 then
  echo Cancel
  goto eoj
endiff
echo Line Selected: %theline
::
:: Create a new path
::
echo %aPath[%theline]
set temppath=%@unique[]
echos set Path= > %temppath
do kount=0 to %SColons
  iff %@len[%aPath[%kount]] gt 0 then
  iff %aPath[%kount] eq %aPath[%theline] then
    echo %aPath[%kount]
   else
    echos %@ltrim[" ",%aPath[%kount]]; >> %temppath
   endiff
  endiff
enddo
echo %@lines[%temppath] > nul
::
:: Number of bytes in the path, minus the trailing Semi-Colon
::
set NoComma=%@dec[%_LINES_MAXLEN]
::
:: Remove the trailing Semi-Colon
::
set newpath=%@unique[]
head /C%NoComma %temppath > %newpath
::
:: Display the new path
::
type %newpath
defer %@line[%newpath,0]
:eoj
if exist %newpath del /q %newpath
if exist %temppath del /q %temppath
if exist %pathlist del /q %pathlist
unsetarray aPath
endlocal

Joe
 
Joe,

A slightly simpler solution would be to export the PATH to a file (as you have done), invoke Notepad to edit as you please, then read the resulting file back into PATH.

Code:
set pl=%@unique[]
echo %@replace[;,^n,%PATH] > %pl
notepad %pl
unset PATH
do p in @%pl (set PATH=%PATH;%p)
del /q %pl
 
My solution in pure TCC/LE, using only variables (no files, no pipes).
Code:
:delFromPath [_fileName]

    *Set _TCC_$retVal=
    *Set _TCC_$extList=%@Replace[;, ,%PATHEXT]
    *If not defined _TCC_$extList *Set _TCC_$extList=.exe .com .lnk .btm .bat .cmd

    *Set _TCC_$nPath=%@dec[%@words[";",%PATH]]
    *Do _TCC_$iPath = 0 to %_TCC_$nPath
        *Set _TCC_$ignore=0

        ::================================================
        :: @Word    - each single directory from PATH
        :: @UnQuote - unquotes
        :: \        - adds extra backslash
        :: @Full    - UnQuotes, removes extra trailing backslashes, clears quirks, resolves ..
        :: @Left    - Removes last backslash
        *Set _TCC_$onPath=%@Left[-1,%@Full[%@UnQuote[%@word[";",%_TCC_$iPath,%PATH]]\]]

        :: Don't touch windows directories
        *Iff %@Index[%_TCC_$onPath\,%windir\] != 0 Then

            :: iterate through all executable extensions, including "no extension"
            *Do _TCC_$ext in /L "" %_TCC_$extList

                *Iff IsFile %@Quote[%_TCC_$onPath\%[_fileName]%@Unquote[%_TCC_$ext]] Then
                    *Set _TCC_$ignore=1
                    *Leave
                *EndIff
            *EndDo

        *EndIff

        *If %_TCC_$ignore == 1 *Iterate

        :: Reconstruct the path

        *If defined _TCC_$retVal *Set _TCC_$retVal=%_TCC_$retVal;
        *Set _TCC_$retVal=%[_TCC_$retVal]%_TCC_$onPath
    *EndDo

    *Set PATH=%_TCC_$retVal

   *UnSet _TCC_$ext
   *UnSet _TCC_$extList
   *UnSet _TCC_$ignore
   *UnSet _TCC_$iPath
   *UnSet _TCC_$nPath
   *UnSet _TCC_$onPath
   *UnSet _TCC_$retVal

    *Return

Example Usage:

GoSub delFromPath word.exe
GoSub delFromPath something.bas
GoSub delFromPath gcc
 
Last edited:
Here's a short one that works pretty well in brief testing. It accepts a wildcard spec (%1) for what you want removed.
Code:
set oldpath=%path
unset /q path
do i=0 to %@dec[%@words[";",%oldpath]]
   set dir=%@word[";",%i,%oldpath]
   if %@wild[%dir,%1] NE 1 set path=%[path]%@if[defined path,;,]%dir
enddo
 
Even simpler - don't add conflicting entries to the system %PATH%.
Only add them when invoking a corresponding development environment.
 
  1. set LOSE=%@execstr[echo %@replace[;,%=n,%PATH]| echo %@select[CON:,1,1,40,40,Remove from path....]]
  2. set PATH=%@replace[%LOSE%;,,%PATH%;]

This will show you a @SELECT-box with the directories of your %PATH%
Select the directory you want to remove from PATH and that's it.
 
  1. set LOSE=%@execstr[echo %@replace[;,%=n,%PATH]| echo %@select[CON:,1,1,40,40,Remove from path....]]
  2. set PATH=%@replace[%LOSE%;,,%PATH%;]
This will show you a @SELECT-box with the directories of your %PATH%
Select the directory you want to remove from PATH and that's it.
Very nice! But

1. What if %LOSE is at the end, and not followed by a semicolon?
2. The pseudovariable '=' doesn't seem to work in v19 or v20.
 
Very nice! But

1. What if %LOSE is at the end, and not followed by a semicolon?
That's why there is a semi-colon at the end of PATH:
%@replace[%LOSE%;,,%PATH%;]


2. The pseudovariable '=' doesn't seem to work in v19 or v20.
I wouldn't know. I just downloaded and installed TCC/LE 14.

[^n] instead of [%=n] should work, though ...
 
Last edited:
Just found this one one my harddisk again (forgot to delete it).
Turns out it has a flaw: if you don't specfy a directory (by pressing [Escape]), it will remove all ";" directory separators and thus render your path useless.

Here is a little improvement. It precedes the current PATH with ";" and removes ;<directory>;. After that it removes the leading ";". The trailing ";" does no harm and can be left there.

Code:
alias UNPATH=`echo %@replace[;,%^n,%PATH]|! set PATH=%@right[-1,%@replace[;%@select[con:,1,1,40,60,Remove from path];,;,;%PATH;]]`
Works in TCC, not in TCC/LE (due to different working of in-process pipes)

I will post this under Tips and Tricks - Aliases too (for consistency)
 
Back
Top