在 中find -name "*.mp3"
,.mp3 前面有一个星号。 不是*
匹配它前面的字符任意次吗?但是星号前面什么都没有,那么 会做什么呢*
?还是因为find
命令不使用正则表达式?那么,.
.mp3 中的 是正则表达式字符还是find
只是将其解释为句点进行匹配?
答案1
谓词-name
采用全局,不是正则表达式。
在正则表达式中,*
将匹配零个或多个前一个项。但由于这是一个 glob,因此它会匹配零个或多个任意字符。也就是说,在 glob 中,与在正则表达式中*
的含义相同。.*
在正则表达式中,.
将精确匹配任意一个字符。但由于这是一个 glob,因此不会对其进行特殊处理,而只是匹配文字.
字符。也就是说,在 glob 中,与在正则表达式中或的.
含义相同。\.
[.]
如果您确实想匹配 glob 中任何字符的单个出现,则可以使用?
。在 glob 中,?
的含义与正则表达式中的含义相同.
。这与正则表达式中的 完全不同?
,后者匹配零个或一个前面的项(即,使前面的项成为可选项)。
唯一的语法大多在 globs 和正则表达式中,相同的是括在 中的字符类[
]
。例如,[aeiou]
匹配任何字符,可以是a
、e
、i
、o
或u
。如果你写一个[
]
在大多数正则表达式方言中都有效的 -delimited 字符类,那么在 glob 中使用时,它也可能是具有相同含义的字符类。
除了作为操作数find
's-name
和-iname
谓词的操作数之外,另一个广泛使用通配符的地方是您的 shell。未加引号的通配符元字符会被您的 shell 自动扩展为与其匹配的文件名相对应的单独参数列表。
这就是为什么在传递给find
。如果不这样做,您的 shell 将尝试扩展它。如果您的 shell 确实扩展了它,find
则不会看到模式本身,而是看到其扩展的结果。这是不可取的,而且常常令人困惑。
请注意,你的 shell(可能是 bash,但一般 Unix 风格的 shell 都是这样的)不会,作为其默认行为,展开?
或*
匹配文件名中的前导点。例如,除非你告诉它要采取其他行为,否则你的 shell 会扩展?
为当前目录中长度为一个字符的文件名,以外.
,即使.
条目始终存在。并且它会扩展*
到当前目录中不以 开头的文件名.
。(在 bash 中,shopt -s dotglob
会为您在其中运行它的 shell 实例更改此设置,并shopt -u dotglob
会恢复默认行为。)只有前导点是特殊的,而不是其他点。
这与和find
谓词的行为不同,其中和始终被允许匹配前导。-name
-iname
?
*
.
答案2
Asterisk(通常称为“通配符”)表示find
返回全部带有扩展名的文件.mp3
。
答案3
因为您使用了双引号,所以bash
会尝试扩展"*.mp3"
全局。
如果有一些*.mp3
如果当前目录中代替全球。
为了演示,echo
在行首放置一个,例如echo find ...
。
如果使用单引号 ( '
),则不会执行 glob 扩展。
使用“ '*.mp3'
”代替“ "*.mp3"
”。