【发布时间】:2013-04-08 09:27:31
【问题描述】:
在编译脚本时,我遇到了命令 do f=${file##*/}。我很想知道这一行中的## 是什么意思。感谢您提前回复
【问题讨论】:
标签: bash shell-exec
在编译脚本时,我遇到了命令 do f=${file##*/}。我很想知道这一行中的## 是什么意思。感谢您提前回复
【问题讨论】:
标签: bash shell-exec
在bash 中,它删除了前缀模式。在这里,它基本上是在最后一个路径分隔符/ 之后为您提供所有内容,方法是贪婪地删除前缀*/,任意数量的字符后跟/):
pax> fspec=/path/to/some/file.txt ; echo ${fspec##*/}
file.txt
在这种情况下,贪婪意味着尽可能多的匹配。还有一个非贪婪的变体(匹配最小的可能序列),以及后缀的等价物:
pax> echo ${fspec#*/} # non-greedy prefix removal
path/to/some/file.txt
pax> echo ${fspec%%/*} # greedy suffix removal (no output)
pax> echo ${fspec%/*} # non-greedy suffix removal
/path/to/some
##*/ 和 %/* 大致相当于您分别从 basename 和 dirname 获得的内容,但在 bash 内,因此您不必调用外部程序:
pax> basename ${fspec} ; dirname ${fspec}
file.txt
/path/to/some
对于它的价值,我记得##、%%、#和%的不同效果的方式如下。它们是各种类型的“去除剂”。
因为# 经常出现在 一个数字之前(如#1),它会在开头删除一些内容。同样,% 通常出现在 一个数字 (50%) 之后,因此它会在末尾删除内容。
那么唯一的区别是贪婪/非贪婪方面。拥有更多角色(## 或 %%)显然意味着你很贪婪,否则你会分享它们:-)
【讨论】:
%%/* 并不是 dirname 的完全替代品。如果您为 dirname 提供一个裸文件名,它会返回 '.',而 %%/* 会返回未更改的名称。 (在一个脚本中,可能会导致使用文件名创建目录而不是识别当前目录已经存在。)
fspec=/path/to/some/file.txt 我想要以下输出:some/file.txt
echo '/path/to/some/file.txt' | perl -pne 's?.*/([^/]*/[^/]*$)?\1?' :-)