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

前端 未结 10 1576
野趣味
野趣味 2020-11-29 17:08

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 d

相关标签:
10条回答
  • 2020-11-29 17:14

    Not so different from previous solutions. However, maybe a bit more readable/editable. However, no solution to the folder name boundary, only focusing on the length of the prompt.

    ### SET MY PROMPT ###
    if [ -n "$PS1" ]; then
        # A temporary variable to contain our prompt command
        NEW_PROMPT_COMMAND='
            pwd_short=${PWD/#$HOME/\~};
            if [ ${#pwd_short} -gt 53 ]; then
                TRIMMED_PWD=${pwd_short: 0: 25}...${pwd_short: -25}
            else
                TRIMMED_PWD=${pwd_short}
            fi
        '
    
        # If there's an existing prompt command, let's not 
        # clobber it
        if [ -n "$PROMPT_COMMAND" ]; then
            PROMPT_COMMAND="$PROMPT_COMMAND;$NEW_PROMPT_COMMAND"
        else
            PROMPT_COMMAND="$NEW_PROMPT_COMMAND"
        fi
    
        # We're done with our temporary variable
        unset NEW_PROMPT_COMMAND
    
        # Set PS1 with our new variable
        # \h - hostname, \u - username
        PS1='\u@\h: $TRIMMED_PWD\$ '
    fi
    

    added to the .bashrc file. All parts of the prompt is updated properly. The first part is shortened if you're in your home directory. Example:

    user@computer: ~/misc/projs/solardrivers...src/com/mycompany/handles$

    0 讨论(0)
  • 2020-11-29 17:22

    For people looking for a much simpler solution and don't need the name of the first directory in the path, Bash has built-in support for this using the PROMPT_DIRTRIM variable. From the documentation:

    PROMPT_DIRTRIM

    If set to a number greater than zero, the value is used as the number of trailing directory components to retain when expanding the \w and \W prompt string escapes (see Printing a Prompt). Characters removed are replaced with an ellipsis.

    For example:

    ~$ mkdir -p a/b/c/d/e/f
    ~$ cd a/b/c/d/e/f
    ~/a/b/c/d/e/f$ export PROMPT_DIRTRIM=2
    ~/.../e/f$ PROMPT_DIRTRIM=3
    ~/.../d/e/f$ 
    

    Downside: It depends on the directory level, not the length of the path, which you might not want.

    Upside: It's very simple. Just add export PROMPT_DIRTRIM=2 to your .bashrc.

    0 讨论(0)
  • 2020-11-29 17:24

    Apart from the bash-builtin solution using PROMPT_DIRTRIM, you may want to try $(pwd | tail -c16), which is a tad simpler than most other answers, but just gives the last 16 characters of the current directory. Of course replace 16 by any number you want.

    0 讨论(0)
  • 2020-11-29 17:25
    echo -n $PWD | sed -re "s|(~?/[^/]*/).*(.{$pwd_length})|\1...\2|"
    

    sed with -r only for convenience, allows to omit backslash before parentheses, and "|" as delimiter only for convenience too - because we want to use the slash inside the command. I guess your home get's displayed as ~ as well, so ~/foo/bar/baz/ should end in ~/foo/.../baz, and /foo/bar/baz/ as /foo/.../baz/.

    So we take an optional ~, followed by slash, name, slash as \1, then something, then the rest as \2.

    0 讨论(0)
  • 2020-11-29 17:30

    Why not just use ${string:position:length}? You can do ${string:-$max_chars} to have the last ${max_chars} of the string.

    note the negative value

    0 讨论(0)
  • 2020-11-29 17:35

    Another approach, still using sed and awk to generate the prompt. This will convert your $HOME directory into ~, show you your root directory, your lowest level (current directory), and its parent, separated by .. for each directory in between.

    Inside of your .bashrc (or .bash_profile on OS X):

    function generate_pwd {
      pwd | sed s.$HOME.~.g | awk -F"/" '
      BEGIN { ORS="/" }
      END {
      for (i=1; i<= NF; i++) {
          if ((i == 1 && $1 != "") || i == NF-1 || i == NF) {
            print $i
          }
          else if (i == 1 && $1 == "") {
            print "/"$2
            i++
          }
          else {
            print ".."
          }
        }
      }'
    }
    export PS1="\$(generate_pwd) -> "
    

    The script uses awk's built in NF variable (number of fields) and positional variables ($1, $2 ...) to print each field (directory name) separated by the ORS variable (output record separator). It collapses the inner directories into .. in your prompt.

    Example of it in use:

    ~/ -> cd Documents/
    ~/Documents/ -> cd scripts/
    ~/Documents/scripts/ -> cd test1/
    ~/../scripts/test1/ -> cd test2
    ~/../../test1/test2/ -> pwd
    /Users/Brandon/Documents/scripts/test1/test2
    ~/../../test1/test2/ -> cd test3/
    ~/../../../test2/test3/ -> cd test4/
    ~/../../../../test3/test4/ -> pwd
    /Users/Brandon/Documents/scripts/test1/test2/test3/test4
    ~/../../../../test3/test4/ -> cd /usr/
    /usr/ -> cd local/
    /usr/local/ -> cd etc/
    /usr/local/etc/ -> cd openssl/
    /usr/../etc/openssl/ -> cd private/
    /usr/../../openssl/private/ ->
    
    0 讨论(0)
提交回复
热议问题