将路径拆分为文件名

use*_*428 1 zsh

在我的 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
Run Code Online (Sandbox Code Playgroud)

特别是,我不喜欢 head 的计算,硬编码值为 11,我想知道是否可能有一种完全不同的方法,这会更优雅。

更新:我知道我的if条件也成立,例如,如果 PWD 是/cygdrive/foo,但对于我的应用程序,我不认为这是一个问题。当然,如果您可以提出更好的替代方案来编写条件,这正是我想要的,我感谢任何评论。

Sté*_*las 5

if [[ $PWD =~ '^(/cygdrive/[abd-z])(.*)' ]]; then
  head=$match[1]
  tail=$match[2]
fi
Run Code Online (Sandbox Code Playgroud)

与 glob 相同:

set -o extendedglob
if [[ $PWD = (#b)(/cygdrive/[abd-z])(*) ]]; then
  head=$match[1]
  tail=$match[2]
fi
Run Code Online (Sandbox Code Playgroud)

Glob 还具有使用zsh自己的模式匹配的优势,其中d-z仅匹配defghijklmnopqrstuvwxyz,而=~将使用您系统的正则表达式,其中[d-z]可以很好地匹配更多字符(例如é甚至dzs匈牙利语言环境中的字符序列)。做 aset -o rematchpcre会导致=~使用在这方面更合理的 PCRE。

不匹配/cygdrive/foo

if [[ $PWD =~ '^(/cygdrive/[abd-z])(/.*)?$' ]]; then
  head=$match[1]
  tail=$match[2]
fi
Run Code Online (Sandbox Code Playgroud)

使用球体:

set -o extendedglob
if [[ $PWD = (#b)(/cygdrive/[abd-z])(/*|) ]]; then
  head=$match[1]
  tail=$match[2]
fi
Run Code Online (Sandbox Code Playgroud)