我实现了一个包含在PS1环境变量中的bash快速路径缩短器,它将工作目录缩短为更紧凑但仍然具有描述性的东西.我很好奇其他想法可能存在.
这是挑战:
创建一个bash函数_dir_chomp,可以像这样包含在PS1中(插入换行符以便于阅读):
PS1='\[\033[01;32m\]\u@\h\[\033[01;34m\] $(
_dir_chomp "$(pwd)" 20
)\[\033[01;37m\]$(parse_git_branch)\[\033[01;34m\] \$\[\033[00m\] '
Run Code Online (Sandbox Code Playgroud)
"20"是最大长度的参数,作为软限制.这些是例子:
/usr/portage/media-plugins/banshee-community-extensions/files 变 /u/p/m/b/files/home/user1/media/video/music/live-sets成为~/m/v/m/live-sets(注意〜字符作为$ HOME的替代)/home/user2/media 不会改变(不超过20个限额)/home/user1/this-is-a-very-long-path-name-with-more-than-20-chars成为~/this-is-a-very-long-path-name-with-more-than-20-chars(最后一个组件保持不变:软限制)/home/user1/src变成~/src($ HOME总是缩短)/home/user1/.kde4/share/config/kresources变成~/.k/s/c/kresources(注意保留前缀点)当前用户是user1.
它允许调用外部口译一样awk,perl,ruby,python但没有编译C程序或类似.换句话说:不允许使用外部源文件,代码必须是内联的.最短版本获胜.bash函数体的长度(和称为子函数)计数,表示:
_sub_helper() {
# this counts
}
_dir_chomp() {
# these characters count (between { and })
_sub_helper "foobar" # _sub_helper body counts, too
}
Run Code Online (Sandbox Code Playgroud)
Pau*_*ce. 12
Pure Bash:
_dir_chomp () {
local IFS=/ c=1 n d
local p=(${1/#$HOME/\~}) r=${p[*]}
local s=${#r}
while ((s>$2&&c<${#p[*]}-1))
do
d=${p[c]}
n=1;[[ $d = .* ]]&&n=2
((s-=${#d}-n))
p[c++]=${d:0:n}
done
echo "${p[*]}"
}
Run Code Online (Sandbox Code Playgroud)
出于测试目的,我假设问题意味着当前用户是"user1".
注意:Bash 4有一个变量PROMPT_DIRTRIM,通过根据其值保留子目录的数量并用其替换其余的来缩短\w转义.PS1...
/$ PROMPT_DIRTRIM=2
/$ echo $PS1
\w\$
/$ pwd
/
/$ cd /usr/share/doc/bash
.../doc/bash$
Run Code Online (Sandbox Code Playgroud)
这个字符比我的其他答案短20个左右:
_dir_chomp () {
local p=${1/#$HOME/\~} b s
s=${#p}
while [[ $p != "${p//\/}" ]]&&(($s>$2))
do
p=${p#/}
[[ $p =~ \.?. ]]
b=$b/${BASH_REMATCH[0]}
p=${p#*/}
((s=${#b}+${#p}))
done
echo ${b/\/~/\~}${b+/}$p
}
Run Code Online (Sandbox Code Playgroud)