如何缩短命令行提示符的当前目录?

paj*_*ton 52 string bash path ps1

我正在使用Ubuntu,当我使用一些深层目录层次结构时,我厌倦了bash中的这个长提示.所以,我想通过以下方式调整我的PS1来缩短工作目录部分:

目前我有:

pajton@dragon:~/workspace/projects/project1/folder1/test$
Run Code Online (Sandbox Code Playgroud)

并希望:

pajton@dragon:~/workspace/.../folder1/test$
Run Code Online (Sandbox Code Playgroud)

如果len($ PWD)超过给定阈值,则会发生截断.我想始终保留第一个路径组件和至少一个最后一个路径组件.然后在空间允许的情况下,从右侧添加更多组件.

这就是我目前所拥有的.它有效,但是:1)不保留第一个路径组件,2)不尊重边界处的切割路径:

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
Run Code Online (Sandbox Code Playgroud)

结果如下:

pajton@dragon:...sth/folder1/sample$ 
Run Code Online (Sandbox Code Playgroud)

提前致谢!

img*_*x64 113

对于寻找更简单的解决方案并且不需要路径中第一个目录的名称的人来说,Bash使用PROMPT_DIRTRIM变量内置了对此的支持.从文档:

PROMPT_DIRTRIM

如果设置为大于零的数字,则该值将用作展开\ w和\ W提示字符串转义时要保留的尾随目录组件的数量(请参阅打印提示).删除的字符将替换为省略号.

例如:

~$ 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$ 
Run Code Online (Sandbox Code Playgroud)

缺点:它取决于目录级别,而不是您可能不需要的路径长度.

好处:这很简单.只需添加export PROMPT_DIRTRIM=2到您的.bashrc.

  • 嗯...这对OSX来说不起作用.我把它放在我的.bash_profile中(在OSX上我认为是合适的......它肯定在新的shell上执行)并且从命令提示符中尝试了"export PROMPT_DIRTRIM = 2". (8认同)
  • 它不适用于从Apple发售的带有bash的OSX(我在Mountain Lion上).发货版本为3.2.48(1) - 发布.如果你使用像Homebrew这样的东西安装最新的bash,你会得到4.2.45(2)-release附近的东西,它支持PROMPT_DIRTRIM. (3认同)
  • 哇,2016年OS X仍在发布bash 3.2.57,(c)2007. (3认同)
  • @LarsH因为bash 3.2是GPLv2 +的最后一个版本.Bash 4.0+是GPLv3 +,Apple对运送GPLv3软件有严格的政策. (2认同)

anu*_*ava 46

对于您的情况,请使用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}$ '
Run Code Online (Sandbox Code Playgroud)

对于你的目录示例,~/workspace/projects/project1/folder1/test它使PS1为:~/workspace/.../folder1/test

UPDATE

上面的解决方案将设置您的提示,但正如您在评论中指出的那样,当您更改目录时,它不会动态更改PS1.所以这里是一个解决方案,当您更改目录时,它将动态设置PS1.

将这两行放在.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}")$ '
Run Code Online (Sandbox Code Playgroud)

if (NF > 4 && length($0) > 14)awk中的条件只会在当前目录深度超过3个目录时应用特殊处理,如果长度$PWD超过14个字符,则保持PS1为$PWD.

例如:如果当前目录是~/workspace/projects/project1$PS1那么~/workspace/projects/project1$

.bashrc中的上述效果将在您的PS1上如下:

~$ cd ~/workspace/projects/project1/folder1/test
~/workspace/.../folder1/test$ cd ..
~/workspace/.../project1/folder1$ cd ..
~/workspace/.../project1$ cd ..
~/.../projects$ cd ..
~/workspace$ cd ..
~$
Run Code Online (Sandbox Code Playgroud)

请注意我更改目录时如何更改提示.如果这不是您想要的,请告诉我.


ray*_*chi 9

这是我根据anubhava的解决方案使用的.它设置提示和Windows标题.awk脚本更具可读性,因此可以轻松调整/自定义.

如果它超过16个字符和4个深度,它将折叠路径.此外,它还将指示...折叠了多少目录,因此您可以了解路径的深度,即:~/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"'
Run Code Online (Sandbox Code Playgroud)

这就是它在行动中的样子.绿色0是最后一个命令的返回码:

在此输入图像描述


use*_*own 5

echo -n $PWD | sed -re "s|(~?/[^/]*/).*(.{$pwd_length})|\1...\2|"
Run Code Online (Sandbox Code Playgroud)

sed with -r只是为了方便,允许在括号前省略反斜杠,并且"|" 作为分隔符也只是为了方便 - 因为我们想在命令中使用斜杠.我想你的家也会显示为〜所以〜/ foo/bar/baz /应该以〜/ foo /.../ baz和/ foo/bar/baz/as /foo /.../baz结尾/.

所以我们选择〜,然后是斜杠,名称,斜杠为\ 1,然后是其他东西,然后其余为\ 2.