Bash:用好的工作目录path自定义PS1
我正在使用Ubuntu,并且我正在使用一些深层的目录层次结构,对bash中的这个长时间提示感到厌倦。 所以,我想调整我的PS1以缩短工作目录部分的方式如下:
目前我有:
pajton@dragon:~/workspace/projects/project1/folder1/test$ 并希望有:
 pajton@dragon:~/workspace/.../folder1/test$ 
如果len($ PWD)通过给定的阈值,则会发生截断。 我想始终保持第一个path组件和至less一个最后一个path组件。 然后,如果空间允许,则从右侧添加更多的组件。
这是我目前的。 它起作用,但是:1)不保留第一path分量,2)不遵守边界处的切割path:
 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 
结果是:
 pajton@dragon:...sth/folder1/sample$ 
提前致谢!
考虑这个脚本使用awk而不是sed你的情况:
 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}$ ' 
 以你的~/workspace/projects/project1/folder1/test目录为例,它使得PS1成为: ~/workspace/.../folder1/test 
UPDATE
上面的解决scheme将设置您的提示,但正如您在评论中指出的那样,当您更改目录时,它不会dynamic更改PS1。 所以这里是当你改变目录时dynamic设置PS1的解决scheme。
把这两行放在你的.bashrc文件中:
 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) awk中的if (NF > 4 && length($0) > 14)条件只会在当前目录超过3个目录并且$PWD长度超过14个字符时才应用特殊处理,否则将保留PS1为$PWD 。 
 例如:如果当前目录是~/workspace/projects/project1$那么PS1将是~/workspace/projects/project1$ 
以上在.bashrc中的效果如下:
 ~$ cd ~/workspace/projects/project1/folder1/test ~/workspace/.../folder1/test$ cd .. ~/workspace/.../project1/folder1$ cd .. ~/workspace/.../project1$ cd .. ~/.../projects$ cd .. ~/workspace$ cd .. ~$ 
注意当我改变目录的时候改变的方式。 让我知道这是不是你想要的。
 对于寻找更简单的解决scheme的人们而言,不需要path中第一个目录的名字,Bash已经使用PROMPT_DIRTRIMvariables为其提供内置的支持。  从文档 : 
PROMPT_DIRTRIM
如果设置为大于零的数字,则将该值用作扩展\ w和\ W提示string转义(请参阅打印提示)时要保留的尾随目录组件的数量。 删除的字符被replace为省略号。
例如:
 ~$ mkdir -pa/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$ 
缺点:它取决于目录级别,而不是path的长度,你可能不想要。
 上行:非常简单。 只需将export PROMPT_DIRTRIM=2添加到您的.bashrc 。 
这是我使用anubhava解决scheme的基础。 它设置提示和窗口标题。 awk脚本更具可读性,因此可以轻松调整/定制。
 如果超过16个字符和4个深度,它将折叠path。 此外,它还会在…中指出折叠了多less个目录,以便了解path有多深,即: ~/usr/..4../path2/path1指示4个级别被折叠。 
 # define the awk script using heredoc notation for easy modification MYPSDIR_AWK=$(cat << 'EOF' BEGIN { FS = OFS = "/" } { sub(ENVIRON["HOME"], "~"); if (length($0) > 16 && NF > 4) print $1,$2,".." NF-4 "..",$(NF-1),$NF else print $0 } EOF ) # my replacement for \w prompt expansion export MYPSDIR='$(echo -n "$PWD" | awk "$MYPSDIR_AWK")' # the fancy colorized prompt: [0 user@host ~]$ # return code is in green, user@host is in bold/white export PS1='[\[\033[1;32m\]$?\[\033[0;0m\] \[\033[0;1m\]\u@\h\[\033[0;0m\] $(eval "echo ${MYPSDIR}")]$ ' # set x/ssh window title as well export PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME%%.*} $(eval "echo ${MYPSDIR}")\007"' 
这是它在行动中的样子。 绿色的0是最后一个命令的返回码:
  
 
 echo -n $PWD | sed -re "s|(~?/[^/]*/).*(.{$pwd_length})|\1...\2|" 
sed和-r只是为了方便,允许在括号之前省略反斜杠,而“|” 作为分隔符也只是为了方便 – 因为我们要在命令中使用斜线。 我猜你的家也会显示为〜,所以〜/ foo / bar / baz /应该以〜/ foo /…/ baz结尾,/ foo / bar / baz / as /foo/…/baz /。
所以我们采取一个可选的〜,其次是斜杠,名字,斜线为\ 1,然后是\ 2。
 另一种方法,仍然使用sed和awk来生成提示。 这将把你的$HOME目录转换成〜,显示你的根目录,最低级别(当前目录)和它的父目录,它们之间用..分隔。 
 在.bashrc (或OS X上的.bash_profile )内部: 
 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) -> " 
 该脚本使用awk内置的NFvariables(字段数)和位置variables( $1, $2 ... )打印由ORSvariables(输出logging分隔符)分隔的每个字段(目录名)。 它将内部目录折叠为..在您的提示。 
它在使用的例子:
 ~/ -> 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/ -> 
 除了使用PROMPT_DIRTRIM的bash-builtin解决schemePROMPT_DIRTRIM ,您可能想要尝试使用$(pwd | tail -c16) ,这比大多数其他答案简单一些,只是给出当前目录的最后16个字符。 当然可以用你想要的任何数字代替16。 
 为什么不使用${string:position:length} ? 你可以做${string:-$max_chars}来获得${string:-$max_chars}的最后${max_chars} 。 
注意负值
与以前的解决scheme没什么不同。 但是,也许更可读/可编辑。 但是,没有解决文件夹名称的界限,只关注提示的长度。
 ### 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 
添加到.bashrc文件中。 提示的所有部分都正确更新。 如果你在你的主目录,第一部分缩短了。 例:
user @ computer:〜/ misc / projs / solardrivers … src / com / mycompany / handles $