Search code examples
bashsedprompt

How to shorten path parts between // in bash


I want my bash prompt paths to be shortened:

~/workspace/project/my-project
# Should be
~/w/p/my-project

This could be achieved by just shortening parts of the path string between // to just the first character.

Is there a way to do this for example in sed?

edit:

Thought someone else looking into this might find what I ended useful so I'm editing it here.

.bashrc:

dir_chomp () {
    pwd | sed "s|^$HOME|~|" 2> /dev/null | sed 's:\(\.\?[^/]\)[^/]*/:\1/:g'
}

parse_git_branch() {
    git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
}

export PS1="\[\033[32m\]\$(dir_chomp)\[\033[33m\]\$(parse_git_branch)\[\033[00m\] $ "

prompt examples (coloring doesn't show):

~/w/e/coolstuff (master) $
~/.c/A/Cache $

Solution

  • If you want to unconditionally shorten all path components, you can do it quite easily with sed:

    sed 's:\([^/]\)[^/]*/:\1/:g'
    

    If you want to also insert ~ at the beginning of paths which start with $HOME, you can add that to the sed command (although this naive version assumes that $HOME does not include a colon).

    sed 's:^'"$HOME"':~:/;s:\([^/]\)[^/]*/:\1/:g'
    

    A better solution is to use bash substitution:

    short_pwd() {
      local pwd=$(pwd)
      pwd=${pwd/#$HOME/\~}
      sed 's:\([^/]\)[^/]*/:\1/:g' <<<"$pwd"
    }
    

    With that bash function, you can then "call" it from your PS1 string:

    $ PS1='$(short_pwd)\$ '
    ~/s/tmp$ PS1='\$ '
    $