Linux正则表达式/通配符揭秘

正则表达式概念

正则表达式是你所定义的模式模板(pattern template),Linux工具可以用它来过滤文本;如果数据匹配模式,它就会被接受并进一步处理;如果数据不匹配模式,它就会被滤掉。正则表达式模式利用通配符来描述数据流中的一个或多个字符,例如

da*```da*参数会让ls命令只列出名字以da开头的文件。文件名中da之后可以有任意多个字符(包括什么也没有)。
1
2
3
4
5
6
7
8
9
10
11

正则表达式是通过正则表达式引擎(regular expression engine)实现的。正则表达式引擎是一套底层软件,负责解释正则表达式模式并使用这些模式进行文本匹配。
#### 正则表达式类型
Linux中的不同应用程序可能会用不同类型的正则表达式;而在Linux中,有两种流行的正则表达式引擎:

> POSIX基础正则表达式(basic regular expression,BRE)引擎,sed编辑器只符合了BRE引擎规范的子集

> POSIX扩展正则表达式(extended regular expression,ERE)引擎,gawk程序用ERE引擎来处理它的正则表达式模式。

#### 处理特殊字符
正则表达式识别的特殊字符包括:```.*[]^${}\+?|()```,如果要用某个特殊字符作为文本字符,就必须用```\```转义

查找$或者正斜线

sed -n ‘/\$/p’ data2
echo “3 / 2” | sed -n ‘/\//p’

^字符会在每个由换行符决定的新数据行的行首检查模式

echo “Books are great” | sed -n ‘/^Book/p’

美元符($)定义了行尾锚点

echo “This book is good” | sed -n ‘/book$/p’

^$组合删除所有空白行

sed ‘/^$/d’ data5

点号字符.用来匹配除换行符之外的任意单个字符,如果在点号字符的位置没有字符,那么模式就不成立。在正则表达式中,空格也是字符,也会被.匹配

sed -n ‘/.at/p’ data6

[]定义字符组,字符组中必须有个字符来匹配相应的位置,例如匹配cat和hat

sed -n ‘/[ch]at/p’ data6

使用3个字符组来涵盖3个字符位置含有大小写的情况

echo “yeS” | sed -n ‘/[Yy][Ee][Ss]/p’

匹配了任意含有数字0、1、2或3的行

sed -n ‘/[0123]/p’ data7

排除匹配

匹配c或h之外的任何字符以及文本模式

sed -n ‘/[^ch]at/p’ data6

区间匹配

每个字符组都会匹配0~9的任意数字

sed -n ‘/^[0-9][0-9][0-9][0-9][0-9]$/p’ data8

新的模式[c-h]at匹配了首字母在字母c和字母h之间的单词

sed -n ‘/[c-h]at/p’ data6

该字符组允许区间a~c、h~m中的字母出现在at文本前

sed -n ‘/[a-ch-m]at/p’ data6

特殊字符组,可以用[[:digit:]]来代替区间[0-9]

在字符后面放置星号表明该字符必须在匹配模式的文本中出现0次或多次,例如u*表明字母u可能出现或不出现在匹配模式的文本中

echo “I’m getting a color TV” | sed -n ‘/colou*r/p’

将点号特殊字符和星号特殊字符组合起来。这个组合能够匹配任意数量的任意字符。

echo “bat” | sed -n ‘/b.*t/p’

星号还能用在字符组上,例如只要a和e字符以任何组合形式出现在b和t字符之间(就算完全不出现也行)

echo “bat” | sed -n ‘/b[ae]*t/p’

显示文件夹中文件绝对目录

ls | sed “s:^:pwd/:”

扩展正则表达式:gawk程序能够识别ERE模式,但sed编辑器不能

问号表明前面的字符可以出现0次或1次

echo “bt” | gawk ‘/be?t/{print $0}’

加号表明前面的字符可以出现1次或多次,但必须至少出现1次

echo “bt” | gawk ‘/b[ae]+t/{print $0}’

花括号{}允许你为可重复的正则表达式指定一个上限

字符e只能出现1次,模式才能匹配

echo “bet” | gawk —re-interval ‘/be{1}t/{print $0}’

字符e可以出现1次或2次,这样模式就能匹配

echo “beet” | gawk —re-interval ‘/be{1,2}t/{print $0}’

圆括号进行表达式分组,当你将正则表达式模式分组时,该组会被视为一个标准字符

结尾的urday分组以及问号,使得模式能够匹配完整的Saturday或缩写Sat

echo “Sat” | gawk ‘/Sat(urday)?/{print $0}’

模式(c|b)a(b|t)会匹配第一组中字母的任意组合以及第二组中字母的任意组合

echo “bab” | gawk ‘/(c|b)a(b|t)/{print $0}’

1
2
3
4
5

#### 正则表达式应用
1. 验证电话号码
2. 解析邮件地址
```^([a-zA-Z0-9_\-\.\+]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$

Linux通配符

bash shell可以使用正则表达式中的一些元字符实现通配(Globbing)功能。通配是把一个包含通配符的非具体文件名扩展存储在计算机,服务器或者网络上的一批具体文件名的过程。(可以看出①通配主要应用匹配文件名上,而正则主要应用于字符串上;②通配符通常只能被shell自解释,正则表达式需要被正则引擎解析;③元字符不同)。最常用的通配符包括正则表达式元字符:

  • ?(匹配任意单个字符,不能匹配“/”字符)
  • *(匹配任意位的任意字符,包括空字符串,不包含对“/”字符的匹配)
  • [](匹配一个单字符范围,如[a-z];[0-9];[a-zBE5-7]表示所有a到z之间的字符和 B、E、5、6、7相匹配;[!abc]匹配除了“a,b,c”这3个字符之外的任意一个字符)
  • {}
  • ^(取反),例如
    1
    2
    3
    4
    * !取反

    > 示例
    >

.txt # 匹配全部后缀为.txt的文件
file?.log # 匹配file1.log, file2.log, …
[a-z]
.log # 匹配a-z开头的.log文件
[^a-z]*.log # 上面的反向匹配
```

备注:反斜杠()或引号(‘, “)都会使通配符失效,例如如: \*, "*", '*'都表示*本身,不通配任何文件