问题
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.
回答1:
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.
回答2:
$ 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.
回答3:
Just in bash:
tmp=":$PATH"
[[ $tmp =~ :[^:]*/SDE/[^:]* ]] && tmp=${tmp/${BASH_REMATCH[0]}/}
PATH=${tmp#:}
来源:https://stackoverflow.com/questions/14124541/bash-removing-path-from-path-variable-and-sed-command