模式匹配的用处
- 用在文件名扩展
$ ls fo*
fo0 foo
- 用在参数和变量扩展
$ var="HelloWorld XXXX!"
$ echo ${var/XXX?/felix}
HelloWorld felix!
- 用在条件表达式
$ if [[ felix = f?lix ]]; then echo Hello; else echo "Who are you?"; fi
Hello
- 用在case语句中
$ case felix in
> f[aeiou]lix) echo Hello ;;
> *) echo "Who are you?" ;;
> esac
Hello
模式匹配的规则
非特殊字符,匹配其本身。
NUL字符不能出现在模式里。
\用于转义特殊字符。
如果要在字面上去匹配特殊字符,则必须用引号。
模式匹配里的特殊字符
*
匹配任何字符串,包括null字符串。
在文件名扩展中,如果开启了globstar选项,**可以匹配所有的文件、文件夹和子文件夹。**/匹配所用的文件夹和子文件夹。
\?
匹配任意单个字符
[…]
匹配其中任何一个字符。
用连字符 - 分隔的一对字符表示范围表达式。 介于这两个字符(包括两个字符)之间的任何字符都将匹配。
$ [[ felix = f[a-z]lix ]] && echo matched
matched
范围表达式中字符的排序顺序由当前语言环境以及LC_COLLATE和LC_ALL变量(如果已设置)的值确定。在C语言环境里,[a-dx-z] 等同于[abcdxyz],但在以字典顺序排序字符的环境下,[a-dx-z] 等同于[aBbCcDdxXyYz]. 可以通过设置环境变量LC_COLLATE和LC_ALL为C, 或者开启globasciiranges选项,就能强制要求范围表达式按照C语言环境排序字符。
如果 [ 后的第一个字符是 ! 或 ^,则匹配所有未包含的字符。
$ [[ felix = f[!0-9]lix ]] && echo matched
matched
如果想匹配 -,就把它放在[ ]里的第一位或最后一位。如果想匹配 ],将其放在第一位。
[:class:]匹配指定字符集。POSIX标准定义了如下字符集:
alnum alpha ascii blank cntrl digit graph lower
print punct space upper word xdigit
例如字word符集匹配字母,数字和字符_
[=c=]匹配与字符c具有同等collation weight的字符
[.symbol.]匹配collating symbol
扩展的模式匹配
如果使用shopt命令开启了extglob选项,可以使用下面列举的扩展模式匹配运算符。在这些运算符里,pattern-list是用 | 分隔的模式列表。可以用这些运算符将模式组合成复合模式。
?(pattern-list)
匹配零个或一个模式
*(pattern-list)
匹配零个、一个或多个模式
+(pattern-list)
匹配一个或多个模式
@(pattern-list)
匹配一个模式
!(pattern-list)
匹配零个模式
针对长字符串的复杂扩展模式匹配速度很慢,尤其是当模式包含alternations且字符串包含多个匹配项时。 对较短的字符串使用单独的匹配项,或者使用字符串数组而不是单个长字符串,可能会更快。