Bash替换,使用一个前导目录组件提供basename
出于GNU屏幕标题的目的,我想获得以其父目录名为前缀的当前目录名。例如,在目录中Bash替换,使用一个前导目录组件提供basename,bash,gnu-screen,dirname,Bash,Gnu Screen,Dirname,出于GNU屏幕标题的目的,我想获得以其父目录名为前缀的当前目录名。例如,在目录中 /home/rhys/share/pkgconfig /home/rhys /home / 产出 share/pkgconfig home/rhys home / 在Bash中,从这样的猜测开始 echo $(basename $(dirname $PWD))/$(basename $PWD) 人们可以找到更好的解决办法 echo $(basename "${PWD%/*}")/${PWD##*/} 我说的
/home/rhys/share/pkgconfig
/home/rhys
/home
/
产出
share/pkgconfig
home/rhys
home
/
在Bash中,从这样的猜测开始
echo $(basename $(dirname $PWD))/$(basename $PWD)
人们可以找到更好的解决办法
echo $(basename "${PWD%/*}")/${PWD##*/}
我说的更好,因为生成的进程少了两个
任何人都有一个可爱的技巧来避免使用
basename
?这是一个可以在每个shell提示符下运行的东西,因此尽可能轻量级会很好。使用bash和awk如何:
awk -F'/' '{print $(NF-1)"/"$NF}' <<<"$PWD"
测试它:
awk -F'/' '{if (NF==2 && $2) {$0=$2} else {$0=$(NF-1)"/"$NF}}1' <<EOF
/home/rhys/share/pkgconfig
/home/rhys
/home
/
EOF
下面是一个将在
bash
4或更高版本中运行的函数:
trim () (
IFS=/
read -a c <<< "$1"
unset c[0]
fragment="${c[*]: -2:2}"
echo "${fragment:-/}"
)
for p in /home/rhys/share/pkgconfig /home/rhys /home /; do
trim "$p"
done
share/pkgconfig
home/rhys
home
/
trim()(
如果=/
读a c
作为一项功能:
last2() { [[ $1 =~ .*/([^/]+/[^/]+)$ ]] && echo "${BASH_REMATCH[1]}" || echo "$1"; }
应该在bash
>=3.2上工作为什么IFS
设置在两个地方?你能不能把IFS=/
移到函数的顶部?我对子shell中应该包含的内容有不同的想法,一旦我决定将整个函数体作为子shell,就没有进行清理:)它很漂亮,但它仍然产生了一个过程。
trim () (
IFS=/
read -a c <<< "$1"
unset c[0]
fragment="${c[*]: -2:2}"
echo "${fragment:-/}"
)
for p in /home/rhys/share/pkgconfig /home/rhys /home /; do
trim "$p"
done
share/pkgconfig
home/rhys
home
/
for p in /home/rhys/share/pkgconfig /home/rhys /home /; do
[[ $p =~ .*/([^/]+/[^/]+)$ ]] && echo "${BASH_REMATCH[1]}" || echo "$p"
done
last2() { [[ $1 =~ .*/([^/]+/[^/]+)$ ]] && echo "${BASH_REMATCH[1]}" || echo "$1"; }