Bash removing path from path variable and sed command

对着背影说爱祢 提交于 2019-12-25 05:32:51

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!