0

Working with this code

What is the most elegant way to remove a path from the $PATH variable in Bash?

export PATH=`echo ${PATH} | awk -v RS=: -v ORS=: '/SDE/ {next} {print}'` | sed 's/:*$//'

In this instance if I run just the:

export PATH=`echo ${PATH} | awk -v RS=: -v ORS=: '/SDE/ {next} {print}'`

I can get the path containing /SDE/ removed; however a : remains. The sed command after I am assuming should remove that. When I run this entire command at once nothing gets removed at all. What is wrong with the sed statement that is causing the path not to update and how can I make the sed command remove the colon : after the /SDE/ path variable is removed.

Community
  • 1
  • 1
user1943219
  • 396
  • 2
  • 5
  • 19
  • It'd be better if you post what is the input and output you want, and what is the current output you get. – Rubens Jan 02 '13 at 15:28
  • See also: [How do I manipulate PATH elements in shell scripts](http://stackoverflow.com/questions/273909/how-do-i-manipulate-path-elements-in-shell-scripts) and the `clnpath` script at [How to keep from duplicating PATH variable in `csh`](http://stackoverflow.com/questions/135754/how-to-keep-from-duplicating-path-variable-in-csh) — the script is Bourne/Korn/Bash, despite the question's subject. – Jonathan Leffler Jan 02 '13 at 15:30

3 Answers3

2

The problem is the placement of the closing back-quote ` in the command:

export PATH=`echo ${PATH} | awk -v RS=: -v ORS=: '/SDE/ {next} {print}'` | sed 's/:*$//'

If you used the recommended $(...) notation, you'd see that this is equivalent to:

export PATH=$(echo ${PATH} | awk -v RS=: -v ORS=: '/SDE/ {next} {print}') | sed 's/:*$//'

which pipes the output of the export operation to sed, but export is silent.

Use:

export PATH=$(echo ${PATH} | awk -v RS=: -v ORS=: '/SDE/ {next} {print}' | sed 's/:*$//')

I have fixed the answer from which the erroneous command was copied verbatim. As tripleee notes in a comment, I'm not wholly convinced by the awk solution, but the question was 'what was wrong with the code' and the answer is 'where the back-quotes are placed'. The awk script does handle removing elements of a PATH at any position in the PATH; the sed script simply ensures there is no trailing : so that there is no implicit use of the current directory at the end of the PATH.

See also: How do I manipulate PATH elements in shell scripts and the clnpath script at How to keep from duplicating PATH variable in csh — the script is for POSIX-ish shells like the Bourne, Korn, Bash shells, despite the question's subject. One difference between clnpath and the notation used here is that clnpath only removes full pathnames; it does not attempt to do partial path element matching:

export PATH=$(clnpath $PATH /opt/SDE/bin)

if the path element to be removed was /opt/SDE/bin. Note that clnpath can be used to maintain LD_LIBRARY_PATH, CDPATH, MANPATH and any other path-like variable; so can the awk invocation, of course.

I note in passing that that the /SDE/ pattern in the awk script will remove /opt/USDER/bin; the slashes in the regex have nothing to do with slashes in the pathname.

Community
  • 1
  • 1
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • This still presupposes that the path you want to remove comes last. You could add colons at the beginning and end, replace any double colon with single, then trim one leading and trailing colon, or, better yet, fix up the empty item in the Awk script. – tripleee Jan 02 '13 at 15:53
0
$ PATH="$( awk -v rmv="/SDE/" -v path="$PATH" 'BEGIN{sub(rmv,"",path); gsub(/:+/,":",path); print path}' )"

The above is a guess since you didn't provide sample input or expected output so it may not be quite what you want but it is the right approach.

Ed Morton
  • 188,023
  • 17
  • 78
  • 185
0

Just in bash:

tmp=":$PATH"
[[ $tmp =~ :[^:]*/SDE/[^:]* ]] && tmp=${tmp/${BASH_REMATCH[0]}/}
PATH=${tmp#:}
glenn jackman
  • 238,783
  • 38
  • 220
  • 352