pull one dir out from $PATH
One of my bad habits is to put many executable file dirs into PATH env variable. I know, I can use aliases or write short script for faster command invoking.
One result was that I have two versions of Java in the PATH. Last week, I put a patch of the java into my machine, but java -version gave me a result I didn't want : another dir in $PATH overrides it. It's very easy to fix the problem (e.g. redefine totally new PATH.) But I like to use more sophisticated method for solving this problem: pull one dir from PATH!
Adding a dir to an env variable is easy, and should have been taught in the first hour of UNIX introduction course. (I skipped it while I was a student at Berkeley, and it was my mistake.)
export PATH=$PATH:<new dir>
export PATH=<new dir>:$PATH
Then, how do we pull one dir out from $PATH? One method I thought was divide and concur. Yes, it's a fundamental subject of Computer Science!
tr(1) command is the basic building block for it. It is a cutter, and it is glue in some sense. tr(1) replaces one char in a string to another.
% echo abcbd |tr 'b' 'e'
If we do echo $PATH | tr ':' '\n', it replaces each colon with line feed (='\n') meaning that it makes multi line text. So grep -v <dir> can remove one line, and then tr '\n' ':" makes the text one line once again. Very Easy.
% echo 'dir_a:dir_b:dir_c' |tr ':' '\n' |grep -v _b |tr '\n' ':'
Ouch! the last char in the string which come out of pipe is L-F, and thus it was replaced with a colon. Moreover,
% echo 'dir_a:dir_b:dir_c' |tr ':' '\n' |grep -v _b |tr '\n' ':' |sed -e 's/:$//'
Nothing came out. Sed(1) needs L-F as the last char of line. it was a hard problem to solve ... I thought of it a while, ... then I found that echo $(...< some cmd process> ...) can add it at end of the line since echo adds L-F as its nature.
% echo $(echo 'dir_a:dir_b:dir_c' |tr ':' '\n' |grep -v _b |tr '\n' ':' ) |sed -e 's/:$//'
And I ended up with the line below:
export PATH=`echo $(echo $PATH |tr ':' '\n' |grep -v <some dir> |tr '\n' ':' ) |sed -e 's/:$//'`
I used it like
% java -version
java version "1.5.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-b64)
Java HotSpot(TM) Server VM (build 1.5.0-b64, mixed mode)
% export PATH=`echo $(echo $PATH |tr ':' '\n' |grep -v JDK |tr '\n' ':' ) |sed -e 's/:$//'`
% java -version
java version "1.5.0_11"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_11-b03)
Java HotSpot(TM) Server VM (build 1.5.0_11-b03, mixed mode)