Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

The Bash prompt supports the \w escape sequence, documented as

\w     the current working directory, with $HOME abbreviated
       with a tilde (uses the value of the PROMPT_DIRTRIM variable)

Is there any way to get a similar abbreviation for an arbitrary string? That is, is there a general command that does something like the following, provided that HOME=/home/user1

/home/user1         → ~
/home/user1/a/1     → ~/a/1
/home/user2/b/2     → ~user2/b/2
/root               → ~root

Sure, I could try something ugly with sed, but that is unlikely to give me the result I want in any case. :-)

The movitation behind this is that I would like to keep the titles in the tabs of my terminals as short as possible, hence abbreviate working directories where possible.

UPDATE: As there doesn’t appear to be a satisfactory solution easily available, and I would like to keep things sufficiently fast, I now went with a simple

pwd | sed -e "s|/root|~root|" -e "s|/home/user1|~|

and something similar for root. As I am the only user on the machine, this currently works more or less. I will keep the question open in case someone comes up with magical-tool-that-solves-all-problems (ideally not written in elisp…).

share|improve this question
“Make everything as simple as possible, but not simpler.” — Albert Einstein. s|/home/user1|~| will change /home/user17 to ~7. – Scott Nov 30 '12 at 19:01

For your own home directory, use dir="${PWD/#$HOME/~}".

To just strip /home/ as glenn suggests, also use dir="${dir/#\/home\//~}".

Converting other users' homedirs is much more complicated, since you have to list all users every time.

  • You can't even stop on the first match, since the few first accounts have a homedir of / which will always match. Instead, it is needed to check the longest prefix, which isn't simple.

  • I often work with servers configured to read user accounts from LDAP, which takes a whole second to list all accounts; meanwhile, Active Directory wouldn't even allow to see the entire list.

share|improve this answer
If you want to assume that "regular" users have home directory beginning with "/home/", then case "$PWD/" in ($HOME/*) dir="${PWD/#$HOME/~}" ;; (/home/*) dir="~${PWD:6}" ;; (*) dir="$PWD" ;; esac; echo "$dir" – glenn jackman Nov 28 '12 at 21:40
@grawity: Yes, I can see that it is somewhat more difficult to get back than forth, but I hope dies last. @Glenn: This already fails for /root. I shall go with a hand-written list instead, but thank you very much for your interest! :) – Claudius Nov 29 '12 at 16:25

For current user, and a string stored in a variable called DIR, this will work: ${DIR/~/\~}

It replaces the expansion of ~, which is either the value of the $HOME variable or the current user's home directory, with a literal ~.

share|improve this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .