我正在寻找一种方法来实现一个响应式工作目录,我至少想要显示第一个和最后一个文件夹.它应该基于终端中的可用.例如$(exprtput cols之类的东西- 35)}.
想象一下当前的工作目录是什么 ~/workspace/i/keep/my/projects/project1/src
然后我想显示提示,如:
~/workspace/../src
如果终端足够大我想拥有:
~/workspace/../project1/src
要么
~/workspace/../projects/project1/src
~/workspace/../my/projects/project1/src
所以前进.
如果有足够的地方,它甚至应该显示完整的路径.为了赢得空间,家庭目录应始终显示为~.
这是否可以在OSX上使用纯bash脚本?
Joh*_*024 13
我想显示提示,如:
~/workspace/../src
这将在使用通常$和空格结束提示时显示该路径样式:
PS1='$(pwd | sed -E -e "s|^$HOME|~|" -e '\''s|^([^/]*/[^/]*/).*(/[^/]*)|\1..\2|'\'') \$ '
Run Code Online (Sandbox Code Playgroud)
虽然我的目的是在OSX的BSD上进行这项工作sed,但我只在Linux上使用GNU进行了测试sed.
此版本仅提供一种输出格式.随着终端变宽,它不会改变格式.
新定义中的关键元素PS1是命令替换.那个命令是:
pwd | sed -E -e "s|^$HOME|~|" -e 's|^([^/]*/[^/]*/).*(/[^/]*)|\1..\2|'
Run Code Online (Sandbox Code Playgroud)
pwd
这会将当前工作目录打印到stdout
"s|^$HOME|~|"
如果路径开头$HOME,请将其替换为~.因为$HOME是shell变量,所以此命令必须是双引号,以便shell执行变量替换$HOME.
's|^([^/]*/[^/]*/).*(/[^/]*)|\1..\2|'
正则表达式由三部分组成:
^([^/]*/[^/]*/)匹配前两个目录并将其保存\1.
.* 这匹配前两个目录之前的任何内容,直到最后一个目录
(/[^/]*)匹配最后一个子目录并将其保存\2.
如果有足够的目录供正则表达式匹配,那么整个路径将替换为\1..\2.
假设我们希望提示的格式随终端的可用宽度而改变,如果有空间则显示更多的最终目录.因此,在一个狭窄的终端中,/home/user/dir1/dir2/dir3/dir4可能会显示为,~/dir1/../dir4但是在更宽的终端中它将显示为, ~/dir1/../dir3/dir4并且在更宽的终端中,它将显示为~/dir1/dir2/dir3/dir4.
在这种情况下:
PS1='$(pwd|awk -F/ -v "n=$(tput cols)" -v "h=^$HOME" '\''{sub(h,"~");n=0.3*n;b=$1"/"$2} length($0)<=n || NF==3 {print;next;} NF>3{b=b"/../"; e=$NF; n-=length(b $NF); for (i=NF-1;i>3 && n>length(e)+1;i--) e=$i"/"e;} {print b e;}'\'') \$ '
Run Code Online (Sandbox Code Playgroud)
因为此解决方案需要更多计算,awk所以使用.
此代码允许用户调整目录列表应占用的终端宽度.这是通过调整代码中的常量来完成的n=0.3*n.如上所述,如果可能,这会将目录显示限制为仅30%的终端宽度.
代码的关键元素是这个命令:
pwd | awk -F/ -v "n=$(tput cols)" -v "h=^$HOME" '{sub(h,"~");n=0.3*n;b=$1"/"$2} length($0)<=n || NF==3 {print;next;} NF>3{b=b"/../"; e=$NF; n-=length(b $NF); for (i=NF-1;i>3 && n>length(e)+1;i--) e=$i"/"e;} {print b e;}'
Run Code Online (Sandbox Code Playgroud)
代码考虑了这些情况:
目录字符串已经足够短了.换句话说,它的长度适合分配的空间.在这种情况下,它按原样显示.
只有三个目录.例如,~/dir1/dir2.我们的格式不允许缩短.因此,对于这种情况,目录字符串按原样显示.
有四个或更多目录,必须缩短目录字符串以适应空间.在这种情况下,目录字符串被分为存储在变量中的开头和存储在变量中b的结尾e.开头包含两个目录和点 - 点字符串,例如~/dir1/../.从最后一个目录开始,e当空间允许时,目录将添加到结束字符串.
awk命令的更多详细信息-F/
这会将字段分隔符设置为/.因此,每个目录将显示为单独的字段.
-v "n=$(tput cols)" -v "h=^$HOME"
这会创建我们需要的两个变量. n具有列中的终端宽度. h有一个正则表达式匹配用户的主目录.
sub(h,"~")
如果路径以用户的主目录开头,则将其替换为~.
n=0.3*n
这为提示中的目录字符串的所需宽度设置了目标.我喜欢目录字符串不太长,因此n=0.3*n将目标设置为列中终端宽度的30%.如其他地方所述,根据您的个人喜好,可以用另一个公式替换.
b=$1"/"$2
b是包含目录字符串开头的变量.在这里,我们将它设置为前两个目录.例如,如果路径是~/dir1/dir2/dir3,则设置b为~/dir1.
length($0)<=n || NF==3 {print;next;}
如果完整的目录字符串不长于我们的目标,n或者如果目录字符串中只有三个目录,则按原样打印出目录字符串,然后退出.
NF>3{b=b"/../"; e=$NF; n-=length(b $NF); for (i=NF-1;i>3 && n>length(e)+1;i--) e=$i"/"e;}
如果我们得到,那么我们的目录字符串需要缩短.因此,我们将缩写字符串添加/../到末尾b.对于第一次试验,我们将结束字符串设置e为最后一个目录.(在awk,NF是字段的数量.因此,$NF是最后一个字段(目录)就行了.)然后,我们从减去n的长度b和e.n剩下的价值是我们剩下的空间量.然后从该行的倒数第二个目录开始,我们尝试一次添加一个目录,e而不会超过我们的目标,即目录字符串应该有多长.
{print b e;}
这将打印提示中使用的最终目录字符串.
要更改目录显示所占用的空间量,我们将读取的命令n=0.3*n(目标为30%宽度)更改为n=1*n(即使$提示符溢出到下一行,也会以全宽度为目标):
PS1='$(pwd|awk -F/ -v "n=$(tput cols)" -v "h=^$HOME" '\''{sub(h,"~");n=1*n;b=$1"/"$2} length($0)<=n || NF==3 {print;next;} NF>3{b=b"/../"; e=$NF; n-=length(b $NF); for (i=NF-1;i>3 && n>length(e)+1;i--) e=$i"/"e;} {print b e;}'\'') \$ '
Run Code Online (Sandbox Code Playgroud)
根据您的喜好,您可能需要其他公式.例如,尝试n=n-10并尝试在提示结束时为您留下一些(但不是很多)可用空间.
PM2Ring建议将$提示始终放在下一行,为此,我们\n在\$提示之前放置一个(换行符):
PS1='$(pwd|awk -F/ -v "n=$(tput cols)" -v "h=^$HOME" '\''{sub(h,"~");n=1*n;b=$1"/"$2} length($0)<=n || NF==3 {print;next;} NF>3{b=b"/../"; e=$NF; n-=length(b $NF); for (i=NF-1;i>3 && n>length(e)+1;i--) e=$i"/"e;} {print b e;}'\'') \n\$ '
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2156 次 |
| 最近记录: |