Search code examples
bashstringpathps1

How can I shortern my command line prompt's current directory?


I am using Ubuntu and I am tired of this long prompts in bash when I am working with some deep directory hierarchy. So, I would like to tweak my PS1 to shorten the working directory part the following way:

Currently I have:

pajton@dragon:~/workspace/projects/project1/folder1/test$

and would like to have:

pajton@dragon:~/workspace/.../folder1/test$

The truncating would occur if len($PWD) passes given threshold. I want to always keep the first path component and at least one last path component. Then as space permits, add more components taking from the right.

This is what I have currently. It works, but: 1) doesn't keep first path component, 2) doesn't respect cutting path at boundaries:

pwd_length=14
pwd_symbol="..."
newPWD="${PWD/#$HOME/~}"

if [ $(echo -n $newPWD | wc -c | tr -d " ") -gt $pwd_length ]
then
   newPWD="...$(echo -n $PWD | sed -e "s/.*\(.\{$pwd_length\}\)/\1/")"
else
   newPWD="$(echo -n $PWD)"
fi

And the result:

pajton@dragon:...sth/folder1/sample$ 

Thanks in advance!


Solution

  • Consider this script using awk instead of sed for your case:

    pwd_length=14
    pwd_symbol="..."
    newPWD="${PWD/#$HOME/~}"
    if [ $(echo -n $newPWD | wc -c | tr -d " ") -gt $pwd_length ]
    then
       newPWD=$(echo -n $newPWD | awk -F '/' '{
       print $1 "/" $2 "/.../" $(NF-1) "/" $(NF)}')
    fi
    PS1='${newPWD}$ '
    

    For your example of directory ~/workspace/projects/project1/folder1/test it makes PS1 as: ~/workspace/.../folder1/test

    UPDATE

    Above solution will set your prompt but as you noted in your comment that it will NOT change PS1 dynamically when you change directory. So here is the solution that will dynamically set PS1 when you change directories around.

    Put these 2 lines in your .bashrc file:

    export MYPS='$(echo -n "${PWD/#$HOME/~}" | awk -F "/" '"'"'{
    if (length($0) > 14) { if (NF>4) print $1 "/" $2 "/.../" $(NF-1) "/" $NF;
    else if (NF>3) print $1 "/" $2 "/.../" $NF;
    else print $1 "/.../" $NF; }
    else print $0;}'"'"')'
    PS1='$(eval "echo ${MYPS}")$ '
    

    if (NF > 4 && length($0) > 14) condition in awk will only apply special handling when your current directory is more than 3 directories deep AND if length of $PWD is more than 14 characters otherwise and it will keep PS1 as $PWD.

    eg: if current directory is ~/workspace/projects/project1$ then PS1 will be ~/workspace/projects/project1$

    Effect of above in .bashrc will be as follows on your PS1:

    ~$ cd ~/workspace/projects/project1/folder1/test
    ~/workspace/.../folder1/test$ cd ..
    ~/workspace/.../project1/folder1$ cd ..
    ~/workspace/.../project1$ cd ..
    ~/.../projects$ cd ..
    ~/workspace$ cd ..
    ~$
    

    Notice how prompt is changing when I change directories. Let me know if this is not what you wanted.