Sed 正则表达式

正则表达式使SED变得强大而高效。使用正则表达式可以解决许多复杂的任务。

本章分为三部分:标准正则表达式 , 正则表达式、POSIX正则表达示。

标准正则表达式

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

$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

行尾($)    -  行尾由dollar($)符号表示。下面的示例打印以" Coelho"结尾的行。

$sed -n '/Coelho$/p' books.txt 

执行上述代码后,您将得到以下输出:

The Alchemist, Paulo Coelho 
The Pilgrimage, Paulo Coelho

单个字符(.)    -  Dot(.)匹配行尾字符以外的任何单个字符。下面的示例显示所有以字符" t"结尾的三个字母词。

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

执行上述代码后,您将得到以下输出:

cat 
bat 
rat 
mat

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

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

执行上述代码后,您将得到以下输出:

Call 
Tall

排他集([^])    -  在排他字符集中,插入号将否定在方括号中的字符集。以下示例仅打印"Ball"。

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

执行上述代码后,您将得到以下输出:

Ball 

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

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

执行上述代码后,您将得到以下输出:

Call 
Tall

现在让我们将范围修改为" A-P"并观察输出。

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

执行上述代码后,您将得到以下输出:

Call 
Ball

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

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

执行上述代码后,您将得到以下输出:

Behaviour 
Behavior

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

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

执行上述代码后,您将得到以下输出:

22 
123 
234 
222 

零次或多次发生(*)     -  星号(*)与前面字符的零个或多个匹配。下面的示例匹配" ca"," cat"," catt"等。

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

执行上述代码后,您将得到以下输出:

ca 
cat 

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

$cat numbers.txt 

执行上述代码后,您将得到以下输出:

1 
10 
100 
1000 
10000 
100000 
1000000 
10000000 
100000000 
1000000000

让我们编写SED表达式。

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

执行上述代码后,您将得到以下输出:

100

请注意,一对花括号用"\"字符转义。

至少发生n次{n,}    -  {n,}至少匹配前一个字符的" n"次出现。下面的示例打印所有大于或等于五位数的数字。

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

执行上述代码后,您将得到以下输出:

10000 
100000 
1000000
10000000 
100000000 
1000000000 

{m,n}至少m,最多n次    -  {m,n}至少匹配" m"个字符,并且最多匹配" n"个字符。下面的示例打印所有具有至少五位数但不超过八位数的数字。

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

执行上述代码后,您将得到以下输出:

10000 
100000 
1000000 
10000000 

管道(|)     -  在SED中,管道字符的行为类似于逻辑OR操作。它匹配管道两侧的项目。以下示例匹配" str1"或" str3"。

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

执行上述代码后,您将得到以下输出:

str1 
str3

请注意,圆括号(|)对用"\"字符转义。

转义字符

有某些特殊字符。例如,换行符用"\n"表示,回车符用"\r"表示,依此类推。要将这些字符用于常规ASCIIcontext,我们必须使用反斜杠(\)字符对其进行转义。

转义"\"    -  下面的示例匹配模式"\"。

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

执行上述代码后,您将得到以下输出:

str1\str2 

转义"\n"    -  下面的示例匹配换行符。

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

执行上述代码后,您将得到以下输出:

str1\nstr2

转义"\r"    -  以下示例匹配回车符。

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

执行上述代码后,您将得到以下输出:

str1\rstr2

转义"\dnnn"    -  这与一个十进制ASCII值为" nnn"的字符匹配。以下示例仅匹配字符" a"。

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

执行上述代码后,您将得到以下输出:

a

转义"\onnn"    -  这与八进制ASCII值为" nnn"的字符匹配。以下示例仅匹配字符" b"。

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

执行上述代码后,您将得到以下输出:

b 

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

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

执行上述代码后,您将得到以下输出:

c

POSIX表达式

有些保留字具有特殊含义,这些保留字称为正则表达式的POSIX类。

[:alnum:]    -  它表示字母和数字字符。以下示例仅匹配"一个"和" 123",但不匹配制表符。

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

执行上述代码后,您将得到以下输出:

One 
123

[:alpha:]     -  它仅表示字母字符。下面的示例仅匹配单词" One"。

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

执行上述代码后,您将得到以下输出:

One 

[:blank:]     -  它表示空白字符,可以是空格或制表符。下面的示例仅匹配制表符。

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

执行上述代码后,您将得到以下输出:

^I$

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

[:digit:]    -  它仅表示十进制数。以下示例仅匹配数字" 123"。

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

执行上述代码后,您将得到以下输出:

123 

[:lower:]    -  仅表示小写字母。以下示例仅匹配"one"。

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

执行上述代码后,您将得到以下输出:

one 

[:upper:]    -  它仅暗示大写字母。以下示例仅匹配"TWO"。

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

执行上述代码后,您将得到以下输出:

TWO

[:punct:]    -  这意味着标点符号包括非空格或字母数字字符

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

执行上述代码后,您将得到以下输出:

One,Two

[:space:]    -  它暗示空白字符。以下示例说明了这一点。

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

执行上述代码后,您将得到以下输出:

123^L^I$

元字符

像传统的正则表达式一样,SED也支持元字符,这些是Perl样式的正则表达式。

字边界(\b)    -  在正则表达式术语中,"\b"与单词边界匹配。例如,"\bthe\b"匹配" the",但不匹配" these"," there"," they"," then"等。以下示例说明了这一点。

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

执行上述代码后,您将得到以下输出:

the

非单词边界(\B)    -  在正则表达式术语中,"\B"匹配非单词边界。例如," the\B"匹配" these"和" they",但不匹配" the"。以下示例说明了这一点。

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

执行上述代码后,您将得到以下输出:

these 
they

单个空格(\s)    -  在SED中,"\s"表示单个空格字符。以下示例匹配" Line\t1",但不匹配" Line1"。

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

执行上述代码后,您将得到以下输出:

Line 1 

单个非空白(\S)    -  在SED中,"\S"表示单个空格字符。以下示例匹配" Line2",但不匹配" Line\t1"。

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

执行上述代码后,您将得到以下输出:

Line2

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

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

执行上述代码后,您将得到以下输出:

One 
123 
1_2

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

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

执行上述代码后,您将得到以下输出:

&;#

模式空间的开始(\`)

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

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

执行上述代码后,您将得到以下输出:

One