我正在使用Ubuntu,当我使用一些深层目录层次结构时,我厌倦了bash中的这个长提示。所以,我想通过以下方式调整我的PS1来缩短工作目录部分:
目前我有:
pajton@dragon:~/workspace/projects/project1/folder1/test$
并希望:
pajton@dragon:~/workspace/.../folder1/test$
如果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
结果:
pajton@dragon:...sth/folder1/sample$
提前致谢!
答案 0 :(得分:113)
对于寻找更简单的解决方案并且不需要路径中第一个目录的名称的人来说,Bash使用PROMPT_DIRTRIM
变量内置了对此的支持。 From the documentation:
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$
下行:取决于目录级别,而不是您可能不需要的路径长度。
上行:这很简单。只需将export PROMPT_DIRTRIM=2
添加到.bashrc
。
答案 1 :(得分:45)
在您的情况下使用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
以上解决方案将设置您的提示,但正如您在评论中指出的那样,当您更改目录时,它不会动态更改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}")$ '
awk中的 if (NF > 4 && length($0) > 14)
条件只会在当前目录深度超过3个目录时应用特殊处理,如果$PWD
的长度超过14个字符,则保持PS1为{{1 }}。
例如:如果当前目录为$PWD
,那么PS1将为~/workspace/projects/project1$
.bashrc中上面的效果在你的PS1上如下:
~/workspace/projects/project1$
注意更改目录时提示符的更改方式。如果这不是您想要的,请告诉我。
答案 2 :(得分: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"'
这就是它在行动中的样子。绿色0是最后一个命令的返回码:
答案 3 :(得分:5)
echo -n $PWD | sed -re "s|(~?/[^/]*/).*(.{$pwd_length})|\1...\2|"
仅为方便起见使用-r,允许在括号前省略反斜杠,并且“|”作为分隔符也只是为了方便 - 因为我们想在命令中使用斜杠。我想你的家也会显示为〜所以〜/ foo / bar / baz /应该以〜/ foo /.../ baz和/ foo / bar / baz / as /foo /.../baz结尾/。
所以我们选择〜,然后是斜杠,名称,斜杠为\ 1,然后是一些东西,然后其余为\ 2。
答案 4 :(得分:3)
另一种方法,仍然使用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
变量(字段数)和位置变量($1, $2 ...
)来打印由ORS
变量分隔的每个字段(目录名)(输出记录)分隔器)。它会在您的提示符中将内部目录折叠为..
。
使用示例:
~/ -> 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/ ->
答案 5 :(得分:1)
除了使用PROMPT_DIRTRIM
的bash-builtin解决方案之外,您可能想尝试$(pwd | tail -c16)
,这比其他大多数答案都简单,但只提供当前目录的最后16个字符。当然,用你想要的任何数字替换16。
答案 6 :(得分:0)
为什么不使用${string:position:length}
?
您可以${string:-$max_chars}
获取字符串的最后${max_chars}
。
注意负值
答案 7 :(得分:0)
与以前的解决方案没那么不同。但是,可能更具可读性/可编辑性。但是,没有解决文件夹名称边界的问题,只关注提示的长度。
### 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 $
答案 8 :(得分:0)
generatePwd(){
set -- "`pwd | sed -e s.${HOME}.~.g`"
IFS="/"; declare -a array=($*)
srt=""
count=0
for i in ${!array[@]}; do
# echo ${array[i]} - $i/${#array[@]}
if [[ $i == 0 ]]; then
srt+=""
elif [[ $i == $((${#array[@]}-1)) ]] || [[ $i == $((${#array[@]}-2)) ]]; then
srt+="/${array[i]}"
else
count=$((${count}+1))
fi
done
if [[ $count != 0 ]]; then
srt="${array[0]}/.$count.$srt"
else
srt="${array[0]}$srt"
fi
echo "${srt}"
}
导出PS1
PS1="\$(generatePwd)"
控制台
$ ~/.3./machine-learning/deep-learning-computer-vision
答案 9 :(得分:0)
https://github.com/chrissound/SodiumSierraStrawberry
允许您截断类似以下路径:
发件人: / home / sodium / Projects / Personal / Sierra / Super / Long / Path / HolyAvacado
致:»项目/ Sie…/ Sup…/ Lon…/ Pat…/ HolyAvacado /
答案 10 :(得分:0)
Raychi 的答案在 Mac/Catalina 上对我很有用。
稍微修改了相应的部分,以“两深”开头。
if (length($0) > 16 && NF > 5)
print $1,$2,$3,".." NF-5 "..",$(NF-1),$NF
结果将类似于:
/Volumes/Work/..3../Python/Tutorials
我的 .bashrc 文件的相关部分作为自包含的复制粘贴解决方案是:
MYPSDIR_AWK=$(cat << 'EOF'
BEGIN { FS = OFS = "/" }
{
sub(ENVIRON["HOME"], "~");
if (length($0) > 16 && NF > 5)
print $1,$2,$3,".." NF-5 "..",$(NF-1),$NF
else
print $0
}
EOF
)
export MYPSDIR='$(echo -n "$PWD" | awk "$MYPSDIR_AWK")'
请注意,以上不包括 Raychi 的 着色方案。如果需要,请单独添加。