启用extglob后,Bash中*(a-z)*与*(a-z)通配匹配差异原因咨询
Bash扩展通配符:
*(a-z)与*(a-z)*的匹配差异解析 关键语法澄清
启用shopt -s extglob后,Bash的扩展通配符*(pattern-list)是一个整体结构,表示匹配零次或多次连续出现的、符合pattern-list中任意模式的字符串。这里的核心误区是:你写的(a-z)不是字符类(字符类用[a-z]表示),而是被当作字面量模式a-z来处理。
两种模式的具体解析
1. ls *(a-z)
这个模式会被解析为:匹配完全由0次或多次字面量a-z组成的文件名。可能的匹配结果是空字符串(无意义,因为没有空文件名)、a-z、a-za-z等。你的目录中只有chair和table,没有符合该规则的文件,因此匹配失败。
2. ls *(a-z)*
这个模式分为两部分:
- 前半部分
*(a-z):可以匹配零次a-z(也就是空字符串) - 后半部分
*:是普通通配符,匹配任意长度的任意字符
两者结合后,整个模式等价于*(空字符串 + 任意字符 = 任意字符),因此会匹配当前目录下的所有文件,也就是chair和table。
验证你的猜想
你之前猜想*(a-z)中的*是普通通配符、(a-z)是字面量的方向有误——启用extglob后,*(...)是一个整体扩展通配符,*不再是普通通配符,而是扩展通配符的一部分。*(a-z)*能匹配所有文件,本质是前半部分的扩展通配符可以匹配空字符串,后半部分的普通*接管了整个文件名的匹配。
正确匹配小写字母组成的文件名
如果你想匹配仅由小写字母组成的文件名,应该用字符类结合扩展通配符,写成:
ls *([a-z])
这个模式表示匹配零次或多次小写字母组成的文件名,会成功匹配chair和table。
内容的提问来源于stack exchange,提问作者gambarimas87
相关产品推荐
相关产品推荐

