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。

另一种方法,仍然使用sedawk来生成提示。 这将把你的$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 $