I rewrote this recently, based on another script I wrote years ago - this one is optimised to run inside bash as much as possible, to avoid costly forks. It was almost 8x faster than my old function that used awk/sed.
It does produce nice results. It keeps the pwd part of the prompt to no more than MAX_PWD_LENGTH characters, and if you're in a subdir of $HOME, it makes this clear too:
Examples:
pc770-ubu:~ $ cd ~/a/b/c
pc770-ubu:~/a/b/c $ cd d/e/f
pc770-ubu:~/a/b/c/d/e/f $ cd g
pc770-ubu:~/a/b/c/d/e/f/g $ cd h
pc770-ubu:~/a/b/c/d/e/f/g/h $ cd i
pc770-ubu:~/a/b/c/d/e/f/g/h/i $ cd j
pc770-ubu:~/a/b/c/d/e/f/g/h/i/j $ cd k
pc770-ubu:~/a/b/c/d/e/f/g/h/i/j/k $ cd l
pc770-ubu:~../c/d/e/f/g/h/i/j/k/l $ cd m
pc770-ubu:~../d/e/f/g/h/i/j/k/l/m $ cd n
pc770-ubu:~../e/f/g/h/i/j/k/l/m/n $ cd o
pc770-ubu:~../f/g/h/i/j/k/l/m/n/o $ cd /tmp/a/b/c/d/e/f
pc770-ubu:/tmp/a/b/c/d/e/f $ cd g
pc770-ubu:/tmp/a/b/c/d/e/f/g $ cd h
pc770-ubu:/tmp/a/b/c/d/e/f/g/h $ cd i
pc770-ubu:/tmp/a/b/c/d/e/f/g/h/i $ cd j
pc770-ubu:/../a/b/c/d/e/f/g/h/i/j $ cd k
pc770-ubu:/../b/c/d/e/f/g/h/i/j/k $ cd l
pc770-ubu:/../c/d/e/f/g/h/i/j/k/l $ cd m
pc770-ubu:/../d/e/f/g/h/i/j/k/l/m $ cd
pc770-ubu:~ $
The bash function (call this when constructing your PS1 variable):
# set this to whatever you want:
MAX_PWD_LENGTH=20
function shorten_pwd
{
# This function ensures that the PWD string does not exceed $MAX_PWD_LENGTH characters
PWD=$(pwd)
# if truncated, replace truncated part with this string:
REPLACE="/.."
# determine part of path within HOME, or entire path if not in HOME
RESIDUAL=${PWD#$HOME}
# compare RESIDUAL with PWD to determine whether we are in HOME or not
if [ X"$RESIDUAL" != X"$PWD" ]
then
PREFIX="~"
fi
# check if residual path needs truncating to keep total length below MAX_PWD_LENGTH
# compensate for replacement string.
TRUNC_LENGTH=$(($MAX_PWD_LENGTH - ${#PREFIX} - ${#REPLACE} - 1))
NORMAL=${PREFIX}${RESIDUAL}
if [ ${#NORMAL} -ge $(($MAX_PWD_LENGTH)) ]
then
newPWD=${PREFIX}${REPLACE}${RESIDUAL:((${#RESIDUAL} - $TRUNC_LENGTH)):$TRUNC_LENGTH}
else
newPWD=${PREFIX}${RESIDUAL}
fi
# return to caller
echo $newPWD
}
EDIT: fixed bug with absolute string length
2
This is a great question, but it's also an exact duplicate of a question (already answered) on Stack Overflow: http://stackoverflow.com/questions/1616678/bash-pwd-shortening
– Telemachus – 2010-08-24T21:40:16.4273It's not actually an exact duplicate, though it is similar. But looking through that I can't easily see exactly how to do what I want - which is not fixed length, but just initials. I might have a go and post the answer here if I succeed. – Hamish Downer – 2010-08-24T22:02:03.070
Fair enough. I posted an answer below, based on that thread. – Telemachus – 2010-08-24T22:13:37.440
1
It's also a duplicate of this one.
– Paused until further notice. – 2010-08-25T01:02:58.620@Telemachus - it is good to refer to a solution from another site, but there is no reason a question can't exist on both sites, if it's on-topic on both. This question is on-topic on super User, it can and should be answered here. – Gnoupi – 2010-08-25T07:47:35.270
It's not a solution but rather an advice. Keep the prompt and the current directory on separate lines, something like:
\w\n\$
. – cYrus – 2012-08-03T17:23:59.913