存在尾随 / 时获取带通配符的基名

getting basename with globbing when trailing / is present

input1="/$HOME/Desktop/foo/bar/"
input2="/$HOME/Desktop/foo/bar"
target1a=$(basename "$input1")
target1b="${input1##*/}"
target2a=$(basename "$input2")
target2b="${input2##*/}"

echo $target1a
echo $target1b
echo $target2a
echo $target2b

returns

bar

bar
bar

有没有办法让 target1b 也变成 return bar

Do to tab completion in bash,</code> 通常可以像 <code>input1input2 变体一样输入到 cli 中,我希望能够当输入任一变体时,使用 globbing 而不是 basename 到 return bar

我假设您希望避免 basename 创建 运行 外部实用程序所需的子进程的开销。

如果是这样,以下使用 Bash 的 regex-matching 运算符 =~ 可能会执行以下操作:

[[ $input1 =~ ([^/]+)/?$ ]] && target1b=${BASH_REMATCH[1]}

正则表达式 ([^/]+)/?$ 捕获最后一个 ($) 路径组件 ([^/]+),不包括尾随 /,如果存在 (/?)。

regex-matching 操作的结果存储在特殊数组变量 ${BASH_REMATCH[@]} 中,Bash 在每次使用 =~ 后填充。
path-component-matching 子表达式匹配的内容作为元素 1 可用,因为它是包含在 (...) 中的第一个(且仅在此处)子表达式,通常称为 捕获组 (元素 0 始终包含整体匹配项)。

我看到你已经接受了 (有道理!),但这里有一个纯粹的 glob,以防它对其他人有所帮助 —

target1b="${input1%/}"       # Strip the trailing slash, if any
target1b="${target1b##*/}"   # Now drop the leading directory components