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_DIRTRIM
variables为其提供内置的支持。 从文档 :
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内置的NF
variables(字段数)和位置variables( $1, $2 ...
)打印由ORS
variables(输出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 $