繁体   English   中英

Shell 参数扩展在 ksh 中工作,但在 bash 中不工作

[英]Shell parameter expansion working in ksh but not in bash

为什么下面的代码在ksh和bash中产生不同的output

p="folderA/folderB/folderC"
echo ${p%%+([^/])}
echo ${p#${p%%+([^/])}}

ksh 输出:

folderA/folderB/
folderC

bash 输出:

folderA/folderB/folderC

我特别困惑,因为我使用了bash 文档来创建这个参数扩展。

我想在最后一个斜杠之后提取文件夹名称。 我发现了另一种在 ksh 和 bash 中工作的方法:

echo ${p##*/}

但我想了解为什么第一种方法不起作用。

+(...)是扩展 glob 语法,您需要为 bash 启用extglob功能才能理解它。 另一个答案所述,通常不应使用抑扬符来否定字符 class。 Bash 可以容忍这个错误,但无论如何,为了可移植性,让我们使用正确的语法:

shopt -s extglob
p="folderA/folderB/folderC"
echo "${p%%+([!/])}"
echo "${p#${p%%+([!/])}}"

产量:

folderA/folderB/
folderC

相关链接: Bash 参考手册§模式匹配


顺便说一句,您实际上并不需要扩展 glob。

p="folderA/folderB/folderC"
echo "${p%${p##*/}}"
echo "${p##*/}"

上面的脚本同样适用于任何符合 POSIX 的 shell。

另一个更符合标准的 Korn shell 实际输出

folderA/folderB/folderC

后跟一个空行。 这是因为 shell glob不是正则表达式,字符 class 协商运算符是假朋友。

在 POSIX shell 中, [^/] 实际上是未指定的,但通常( ["^"/]更清楚)表示“ ^/ ”,但您会想要“任何不是/的东西”,在 POSIX shell [!/][!/]代替。

有关 GNU bash 如何需要shopt -s extglob以另外支持 Korn shell 兼容的扩展通配模式的解释,请参见其他答案

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM