在我的 zsh 脚本中,我想知道我的工作目录是否以以下开头/cygdrive/?/...
或完全匹配/cygdrive/?
(其中驱动器号(?)可以是与字母 c 不同的任何字母),如果是,则检索到两个变量/cygdrive/?
部分和剩余的/...
。示例:如果我的工作目录是/cygdrive/r/abc/xyz
,我希望将变量head
设置为/cygdrive/r
并将变量tail
设置为/abc/xyz
。例如,如果 PWD 只是 ,则/cygdrive/r
该变量tail
应该为空。
我更喜欢仅使用 zsh 内部命令的解决方案,即不需要生成进程。
我想出了以下解决方案,它可以完成工作,但我不喜欢它:
if [[ $PWD == /cygdrive/[abd-z]* ]]
then
local head=${PWD:0:11}
local tail=${PWD#/cygdrive/?}
....
fi
特别是,我不喜欢 head 的计算,其硬编码值为 11,我想知道是否可能有一种完全不同的方法,这会更优雅。
更新:我知道我的if
条件也成立,例如,如果 PWD 是 ,/cygdrive/foo
但对于我的应用程序,我不认为这是一个问题。当然,如果你能建议一个更好的替代方案来编写条件,确切地做我想做的事,我感谢任何评论。
答案1
if [[ $PWD =~ '^(/cygdrive/[abd-z])(.*)' ]]; then
head=$match[1]
tail=$match[2]
fi
与全局相同:
set -o extendedglob
if [[ $PWD = (#b)(/cygdrive/[abd-z])(*) ]]; then
head=$match[1]
tail=$match[2]
fi
zsh
Glob 还具有使用自身模式匹配的优势,其中d-z
仅匹配defghijklmnopqrstuvwxyz
,而=~
会使用系统的正则表达式,其中[d-z]
可能非常匹配更多字符(例如é
甚至dzs
匈牙利地区中的字符序列)。执行set -o rematchpcre
会导致=~
使用 PCRE,在这方面这更合理。
不匹配/cygdrive/foo
:
if [[ $PWD =~ '^(/cygdrive/[abd-z])(/.*)?$' ]]; then
head=$match[1]
tail=$match[2]
fi
与球:
set -o extendedglob
if [[ $PWD = (#b)(/cygdrive/[abd-z])(/*|) ]]; then
head=$match[1]
tail=$match[2]
fi
答案2
由于您已经知道如何获取变量的后缀,因此可以将其从变量中删除以具有前缀:
if [[ $PWD == /cygdrive/[abd-z] ]]
then
local tail=${PWD#/cygdrive/?}
local head=${PWD%%$tail}
....
fi
至于条件,可以在Zsh中使用正则表达式:
if [[ $PWD =~ '^/cygdrive/[abd-z](/.*)?$' ]]
then
tail=${PWD#/cygdrive/?}
head=${PWD%%$tail}
echo "head is $head"
echo "tail is $tail"
else
echo "no match"
fi