Linux shell 学习笔记(15)— shell 正则表达式

    xiaoxiao2022-07-07  168

    1. 定义 BRE 模式

    1.1 纯文本

    第一条原则就是:正则表达式模式都区分大小写。这意味着它们只会匹配大小写也相符的模式。

    $ echo "This is a test" | sed -n '/this/p' $ $ echo "This is a test" | sed -n '/This/p' This is a test $

    在正则表达式中,你不用写出整个单词。只要定义的文本出现在数据流中,正则表达式就能够匹配。

    $ echo "The books are expensive" | sed -n '/book/p' The books are expensive $

    1.2 特殊字符

    正则表达式识别的特殊字符包括:.*[]^${}+?|()

    如果要用某个特殊字符作为文本字符,就必须转义。转义字符就是反斜线(\)。

    由于反斜线是特殊字符,如果要在正则表达式模式中使用它,你必须对其转义,这样就产生了两个反斜线。

    $ echo "\ is a special character" | sed -n '/\\/p' \ is a special character $

    要使用正斜线,也需要进行转义。

    $ echo "3 / 2" | sed -n '/\//p' 3 / 2 $

    1.3 锚字符

    锁定在行首

    脱字符(^)定义从数据流中文本行的行首开始的模式。如果模式出现在行首之外的位置,正则表达式模式则无法匹配。

    要用脱字符,就必须将它放在正则表达式中指定的模式前面。

    $ echo "The book store" | sed -n '/^book/p' $ $ echo "Books are great" | sed -n '/^Book/p' Books are great $

    如果你将脱字符放到模式开头之外的其他位置,那么它就跟普通字符一样,不再是特殊字符了:

    $ echo "This ^ is a test" | sed -n '/s ^/p' This ^ is a test $

    由于脱字符出现在正则表达式模式的尾部,sed 编辑器会将它当作普通字符来匹配。

    锁定在行尾

    特殊字符美元符($)定义了行尾锚点。将这个特殊字符放在文本模式之后来指明数据行必须以该文本模式结尾。

    $ echo "This is a good book" | sed -n '/book$/p' This is a good book $ echo "This book is good" | sed -n '/book$/p' $

    组合锚点

    可以在同一行中将行首锚点和行尾锚点组合在一起使用。

    $ cat data4 this is a test of using both anchors I said this is a test this is a test I'm sure this is a test. $ sed -n '/^this is a test$/p' data4 this is a test $

    将两个锚点直接组合在一起,之间不加任何文本,这样过滤出数据流中的空白行。

    $ cat data5 This is one test line. This is another test line. $ sed '/^$/d' data5 This is one test line. This is another test line. $

    定义的正则表达式模式会查找行首和行尾之间什么都没有的那些行。

    1.4 点号字符

    特殊字符点号用来匹配除换行符之外的任意单个字符。它必须匹配一个字符,如果在点号字符的位置没有字符,那么模式就不成立。

    $ cat data6 This is a test of a line. The cat is sleeping. That is a very nice hat. This test is at line four. at ten o'clock we'll go home. $ sed -n '/.at/p' data6 The cat is sleeping. That is a very nice hat. This test is at line four. $

    1.5 字符组

    可以定义用来匹配文本模式中某个位置的一组字符。使用方括号来定义一个字符组。方括号中包含所有你希望出现在该字符组中的字符。

    $ sed -n '/[ch]at/p' data6 The cat is sleeping. That is a very nice hat. $

    字符组不必只含有字母,也可以在其中使用数字。

    $ cat data7 This line doesn't contain a number. This line has 1 number on it. This line a number 2 on it. This line has a number 4 on it. $ sed -n '/[0123]/p' data7 This line has 1 number on it. This line a number 2 on it. $

    1.6 排除型字符组

    在正则表达式模式中,也可以反转字符组的作用。可以寻找组中没有的字符,而不是去寻找组中含有的字符。只要在字符组的开头加个脱字符。

    $ sed -n '/[^ch]at/p' data6 This test is at line four. $

    通过排除型字符组,正则表达式模式会匹配c或h之外的任何字符以及文本模式。由于空格字符属于这个范围,它通过了模式匹配。但即使是排除,字符组仍然必须匹配一个字符,所以以 at 开头的行仍然未能匹配模式。

    1.7 区间

    可以用单破折线符号在字符组中表示字符区间。只需要指定区间的第一个字符、单破折线以及区间的最后一个字符就行了。

    $ sed -n '/^[0-9][0-9][0-9][0-9][0-9]$/p' data8 60633 46201 45902 $

    同样的方法也适用于字母。

    $ sed -n '/[c-h]at/p' data6 The cat is sleeping. That is a very nice hat. $

    1.8 特殊字符数组

    组描述[[:alpha:]]匹配任意字母字符,不管是大写还是小写[[:alnum:]]匹配任意字母数字字符09、AZ或a~z[[:blank:]]匹配空格或制表符[[:digit:]]匹配0~9之间的数字[[:lower:]]匹配小写字母字符a~z[[:print:]]匹配任意可打印字符[[:punct:]]匹配标点符号[[:space:]]匹配任意空白字符:空格、制表符、NL、FF、VT和CR[[:upper:]]匹配任意大写字母字符A~Z $ echo "abc" | sed -n '/[[:digit:]]/p' $ $ echo "abc" | sed -n '/[[:alpha:]]/p' abc $ echo "abc123" | sed -n '/[[:digit:]]/p' abc123 $ echo "This is, a test" | sed -n '/[[:punct:]]/p' This is, a test $ echo "This is a test" | sed -n '/[[:punct:]]/p' $

    1.9 星号

    在字符后面放置星号表明该字符必须在匹配模式的文本中出现 0 次或多次。

    $ echo "ik" | sed -n '/ie*k/p' ik $ echo "iek" | sed -n '/ie*k/p' iek $ echo "ieek" | sed -n '/ie*k/p' ieek $ echo "ieeek" | sed -n '/ie*k/p' ieeek $ echo "ieeeek" | sed -n '/ie*k/p' ieeeek $

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

    $ echo "this is a regular pattern expression" | sed -n ' > /regular.*expression/p' this is a regular pattern expression $

    2. 扩展正则表达式

    2.1 问号

    问号表明前面的字符可以出现 0 次或 1 次,但只限于此。它不会匹配多次出现的字符。

    $ echo "bt" | gawk '/be?t/{print $0}' bt $ echo "bet" | gawk '/be?t/{print $0}' bet $ echo "beet" | gawk '/be?t/{print $0}' $ $ echo "beeet" | gawk '/be?t/{print $0}' $

    2.2 加号

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

    $ echo "beeet" | gawk '/be+t/{print $0}' beeet $ echo "beet" | gawk '/be+t/{print $0}' beet $ echo "bet" | gawk '/be+t/{print $0}' bet $ echo "bt" | gawk '/be+t/{print $0}' $

    2.3 花括号

    m:正则表达式准确出现 m 次。

    m, n:正则表达式至少出现 m 次,至多 n 次。

    $ echo "bt" | gawk --re-interval '/be{1,2}t/{print $0}' $ $ echo "bet" | gawk --re-interval '/be{1,2}t/{print $0}' bet $ echo "beet" | gawk --re-interval '/be{1,2}t/{print $0}' beet $ echo "beeet" | gawk --re-interval '/be{1,2}t/{print $0}' $

    2.4 管道符号

    管道符号允许你在检查数据流时,用逻辑 OR 方式指定正则表达式引擎要用的两个或多个模式。

    使用管道符号的格式如下:expr1|expr2|…

    正则表达式和管道符号之间不能有空格,否则它们也会被认为是正则表达式模式的一部分。

    $ echo "The cat is asleep" | gawk '/cat|dog/{print $0}' The cat is asleep $ echo "The dog is asleep" | gawk '/cat|dog/{print $0}' The dog is asleep $ echo "The sheep is asleep" | gawk '/cat|dog/{print $0}' $

    管道符号两侧的正则表达式可以采用任何正则表达式模式(包括字符组)来定义文本。

    $ echo "He has a hat." | gawk '/[ch]at|dog/{print $0}' He has a hat. $

    2.5 表达式分组

    正则表达式模式也可以用圆括号进行分组。当你将正则表达式模式分组时,该组会被视为一个标准字符。可以像对普通字符一样给该组使用特殊字符。

    $ echo "Sat" | gawk '/Sat(urday)?/{print $0}' Sat $ echo "Saturday" | gawk '/Sat(urday)?/{print $0}' Saturday $
    最新回复(0)