流编辑器 - 正则表达式

正则表达式使SED强大而高效.使用正则表达式可以解决许多复杂的任务.任何命令行专家都知道正则表达式的强大功能.

与许多其他GNU/Linux实用程序一样,SED也支持正则表达式,通常称为正则表达式.本章详细介绍了正则表达式.本章分为三个部分:标准正则表达式,正则表达式的POSIX类和元字符.

标准正则表达式

行开头(^)

在正则表达式术语中,插入符号(^)符号与行的开头匹配.以下示例打印以"The"模式开头的所有行.

[jerry]$ sed -n '/^The/ p' books.txt


执行上述代码后,您会得到以下结果:

The Two Towers, J. R. R. Tolkien 
The Alchemist, Paulo Coelho 
The Fellowship of the Ring, J. R. R. Tolkien 
The Pilgrimage, Paulo Coelho


行尾($)

行尾由美元($)符号表示.以下示例打印以"Coelho"结尾的行.

[jerry]$ sed -n '/Coelho$/ p' books.txt


在执行上述代码时,您会得到以下结果:

The Alchemist, Paulo Coelho 
The Pilgrimage, Paulo Coelho


单字符(.)

点(.)匹配除行尾字符之外的任何单个字符.以下示例打印以字符"t"结尾的所有三个字母单词.

[jerry]$ echo -e "cat\nbat\nrat\nmat\nbatting\nrats\nmats" | sed -n '/^..t$/p'


在执行上述代码时,您会得到以下结果:

cat 
bat 
rat 
mat


匹配字符集([])

在正则表达式术语中,字符集用方括号([])表示.它仅用于匹配多个字符中的一个.以下示例匹配模式"Call"和"Tall"但不匹配"Ball".

[jerry]$ echo -e "Call\nTall\nBall" | sed -n '/[CT]all/ p'


在执行上述代码时,您会得到以下结果:

Call 
Tall


独家套装([^])

在独占集中,插入符号否定了方括号中的字符集.以下示例仅打印"Ball".

[jerry]$ echo -e "Call\nTall\nBall" | sed -n '/[^CT]all/ p'


在执行上述代码时,您会得到以下结果:

Ball


字符范围([ - ])

提供字符范围时,正则表达式匹配方括号中指定范围内的任何字符.以下示例匹配"Call"和"Tall"但不匹配"Ball".

[jerry]$ echo -e "Call\nTall\nBall" | sed -n '/[C-Z]all/ p'


在执行上述代码时,您会得到以下结果:

Call 
Tall


现在让我们将范围修改为"AP"并观察结果.

[jerry]$ echo -e "Call\nTall\nBall" | sed -n '/[A-P]all/ p'


在执行上述代码时,您会得到以下结果:

 Call 
 Ball


一次出现零(\?)

在SED中,问号(\?)匹配前一个字符的零次或一次出现.以下示例匹配"行为"以及"行为".在这里,我们使用"\?"将"u"作为可选字符.

[jerry]$ echo -e "Behaviour\nBehavior" | sed -n '/Behaviou\?r/ p'


在执行上述代码时,您会得到以下结果:

Behaviour 
Behavior


一次或多次出现(\ +)

在SED中,加号(\ +)匹配前一个字符的一个或多个匹配项.以下示例匹配一个或多个"2"的出现.


[jerry]$ echo -e "111\n22\n123\n234\n456\n222"  | sed -n '/2\+/ p'

在执行上述代码时,您会得到以下结果:

22 
123 
234 
222


零次或多次出现(*)

星号(*)匹配前一个字符的零次或多次出现.以下示例匹配"ca","cat","catt"等.

[jerry]$ echo -e "ca\ncat" | sed -n '/cat*/ p'


在执行上述代码时,您会得到以下结果:

ca 
cat


恰好N次出现{n}

{n}恰好匹配前一个字符的"n"次出现.以下示例仅打印三位数字.但在此之前,您需要创建以下仅包含数字的文件.

[jerry]$ cat numbers.txt


在执行上述代码时,您会得到以下结果:

 
 1 
 10 
 100 
 1000 
 10000 
 100000 
 1000000 
 10000000 
 100000000 
 1000000000


让我们写出SED表达式.

[jerry]$ sed -n '/^[0-9]\{3\}$/ p' numbers.txt


在执行上述代码时,您会得到以下结果:

100


请注意,这对花括号被""转义字符.

至少n次出现{n,}

{n,}匹配前面字符的至少"n"次出现.以下示例打印所有大于或等于五位的数字.

[jerry]$ sed -n '/^[0-9]\{5,\}$/ p' numbers.txt


在执行上述代码时,您会得到以下结果:

10000 
100000 
1000000
10000000 
100000000 
1000000000


M到N出现次数{m,n}

{m,n}至少匹配"m"且最多出现"n"次前面的字符.以下示例打印所有具有至少五位但不超过八位的数字.

[jerry]$ sed -n '/^[0-9]\{5,8\}$/ p' numbers.txt


在执行上述代码时,您会得到以下结果:

 
 10000 
 100000 
 1000000 
 10000000


管道(|)

在SED中,管道字符的行为类似于逻辑OR运算.它匹配管道两侧的项目.以下示例匹配"str1"或"str3".

[jerry]$ echo -e "str1\nstr2\nstr3\nstr4" | sed -n '/str\(1\|3\)/ p'


在执行上述代码时,您会得到以下结果:

str1 
str3


注意一对括号和管道(|)由""字符转义.

转义字符

有某些特殊字符.例如,换行符由"\ n"表示,回车符由"\ r"表示,依此类推.要将这些字符用于常规ASCII上下文,我们必须使用反斜杠(\)字符来转义它们.本章说明了特殊字符的转义.

转义""

以下示例匹配模式"".

[jerry]$ echo 'str1\str2' | sed -n '/\\/ p'


在执行上述代码时,您会得到以下结果:

str1\rstr2


转义"\ n"

以下示例匹配新行字符.

[jerry]$ echo 'str1\nstr2' | sed -n '/\\n/ p'


在执行上述代码时,您会得到以下结果:

str1\str2


转义"\ r"

以下示例匹配回车符.

[jerry]$ echo 'str1\rstr2' | sed -n '/\\r/ p'


在执行上述代码时,您会得到以下结果:

str1\rstr2


转义"\dnnn"

匹配十进制ASCII值为"nnn"的字符.以下示例仅匹配字符"a".

[jerry]$ echo -e "a\nb\nc" | sed -n '/\d97/ p'


在执行上述代码时,您会得到以下结果:

a


转义"\ nonnn"

这匹配一个角色其八进制ASCII值为"nnn".以下示例仅匹配字符"b".

[jerry]$ echo -e "a\nb\nc" | sed -n '/\o142/ p'


在执行上述代码时,您会得到以下结果:

b


这匹配十六进制ASCII值为"nnn"的字符.以下示例仅匹配字符"c".

[jerry]$ echo -e "a\nb\nc" | sed -n '/\x63/ p'


在执行上述代码时,您会得到以下结果:

c


POSIX正则表达式类

有一些保留字这有特殊意义.这些保留字称为正则表达式的POSIX类.本节描述了SED支持的POSIX类.

[:alnum:]

它表示字母和数字字符.以下示例仅匹配"一"和"123",但与制表符不匹配.

[jerry]$ echo -e "One\n123\n\t" | sed -n '/[[:alnum:]]/ p'


在执行上述代码时,您会得到以下结果:

One 
123


[:alpha:]

它仅表示字母字符.以下示例仅匹配单词"One".

[jerry]$ echo -e "One\n123\n\t" | sed -n '/[[:alpha:]]/ p'


在执行上述代码时,您会得到以下结果:

One


[:blank:]

它暗示空白字符,可以是空格或制表符.以下示例仅匹配制表符.

[jerry]$ echo -e "One\n123\n\t" | sed -n '/[[:space:]]/ p' | cat -vte


在执行上述代码时,您会得到以下结果:

^I$


请注意,命令"cat -vte"用于显示制表符(^ I).

[:digit:]

它仅表示十进制数字.以下示例仅匹配数字"123".

[jerry]$ echo -e "abc\n123\n\t" | sed -n '/[[:digit:]]/ p'


在执行上述代码时,您会得到以下结果:

123


[:lower:]

它仅暗示小写字母.以下示例仅匹配"one".

[jerry]$ echo -e "one\nTWO\n\t" | sed -n '/[[:lower:]]/ p'


在执行上述代码时,您会得到以下结果:

one


[:upper:]

它仅表示大写字母.以下示例仅匹配"TWO".

[jerry]$ echo -e "one\nTWO\n\t" | sed -n '/[[:upper:]]/ p'


在执行上述代码时,您会得到以下结果:

TWO


[:punct:]

它表示包含非空格或字母数字字符的标点符号

[jerry]$ echo -e "One,Two\nThree\nFour" | sed -n '/[[:punct:]]/ p'


在执行上述代码时,您会得到以下结果:

One,Two


[:space:]

它意味着空格字符.以下示例说明了这一点.

[jerry]$ echo -e "One\n123\f\t" | sed -n '/[[:space:]]/ p' | cat -vte


在执行上述代码时,您会得到以下结果:

123^L^I$


元字符

与传统正则表达式一样,SED也支持元字符.这些是Perl样式的正则表达式.请注意,元字符支持特定于GNU SED,可能无法与其他SED变体一起使用.让我们详细讨论元字符.

字边界(\b)

在正则表达式术语中,"\ b"匹配字边界.例如,"\ bthe \ b"匹配"the"但不匹配"this","there","they","then"等等.以下示例说明了这一点.

[jerry]$ echo -e "these\nthe\nthey\nthen" | sed -n '/\bthe\b/ p'


在执行上述代码时,您会得到以下结果:

 the


非Word边界(\B)

在正则表达式术语中,"\ B"匹配非单词边界.例如,"the \ B"匹配"这些"和"它们"但不匹配"它们".以下示例说明了这一点.

[jerry]$ echo -e "these\nthe\nthey" | sed -n '/the\B/ p'


在执行上述代码时,您会得到以下结果:

these 
they


单个空白(\s)

在SED中,""表示单个空白字符.以下示例匹配"Line \t1"但与"Line1"不匹配.

[jerry]$ echo -e "Line\t1\nLine2" | sed -n '/Line\s/ p'


在执行上述代码时,您会得到以下结果:

Line 1


单个非空白(\S)

在SED中,"\ S"表示单个空白字符.以下示例匹配"Line2"但与"Line \t1"不匹配.

[jerry]$ echo -e "Line\t1\nLine2" | sed -n '/Line\S/ p'


在执行上述代码时,您会得到以下结果:

Line2


单字字符(\w)

在SED中,"\ w"表示单个字符,即字母字符,数字和下划线(_).以下示例说明了这一点.

[jerry]$ echo -e "One\n123\n1_2\n&;#" | sed -n '/\w/ p'


在执行上述代码时,您会得到以下结果:

One 
123 
1_2


单个非单词字符(\W)

在SED中,"\ W"表示单个非单词字符,与"\w"完全相反.以下示例说明了这一点.

[jerry]$ echo -e "One\n123\n1_2\n&;#" | sed -n '/\W/ p'


在执行上述代码时,您会得到以下结果:

&;#


模式空间的开头(\`)

在SED中,"\`"表示模式空间的开始.以下示例仅匹配单词"One".

[jerry]$ echo -e "One\nTwo One" | sed -n '/\`One/ p'


在执行上述代码时,您会得到以下结果:

One