Awk 入门/搜索模式 (1)
如你所知,Awk 会逐行遍历文件,并对匹配搜索模式的每一行执行代码块。到目前为止,我们只使用了非常简单的搜索模式,例如 /gold/
,但你现在将学习更高级的搜索模式。本页上的搜索模式被称为正则表达式。正则表达式是一组规则,可以匹配特定的字符序列。
可以指定的 最简单 的搜索模式类型是简单字符串,用正斜杠 (/
) 括起来。例如
/The/
这会搜索包含字符串 "The" 的任何行。这不会匹配 "the",因为 Awk 是区分大小写的,但它会匹配像 "There" 或 "Them" 这样的单词。
这是最原始的搜索模式。Awk 定义了特殊字符或元字符,可以用来使搜索更具体。例如,在字符串前面加上 ^
("插入符号") 会告诉 Awk 在输入行的开头搜索字符串。例如
/^The/
这会匹配任何以字符串 "The" 开头的行。包含 "The" 但不以其开头的行将不会匹配。
类似地,在字符串后面加上 $
会匹配任何以搜索模式结尾的行。例如
/The$/
在本例中,不以 "The" 结尾的行将不会匹配。
但是,如果我们实际上想在文本中搜索 ^
或 $
这样的字符呢?很简单,我们只需在字符前面加上反斜杠 (\
) 即可。例如
/\$/
这将匹配任何包含 "$" 的行。
有许多不同的元字符可用于自定义搜索模式。
可以使用方括号 ([]
) 指定一组备选字符
/[Tt]he/
此示例匹配字符串 "The" 和 "the"。还可以指定字符范围。例如
/[a-z]/
这会匹配 "a" 到 "z" 之间的任何字符,以及
/[a-zA-Z0-9]/
这会匹配任何字母或数字。
还可以通过在范围前面加上 ^
来排除字符范围。这与匹配字符串开头的插入符号不同,因为它位于方括号内。例如
/^[^a-zA-Z0-9]/
这会匹配任何不以字母或数字开头的行。实际上,你可以在字符集中包含插入符号,确保它不是列出的第一个字符。
竖线 (|
) 允许将正则表达式进行逻辑 OR 操作。例如
/(^Germany)|(^Netherlands)/
这会匹配以单词 "Germany" 或单词 "Netherlands" 开头的行。请注意如何使用括号对这两个表达式进行分组。
点 (.
) 允许 "通配符" 匹配,这意味着它可以用于指定任何任意字符。例如
/f.n/
这将匹配 "fan"、"fun"、"fin",以及 "fxn"、"f4n",以及任何其他以 f 开头,一个字符,然后以 n 结尾的字符串。
这种点通配符的使用对于 UNIX shell 用户来说应该很熟悉,但 Awk 对 *
通配符的解释略有不同。在 UNIX shell 中,*
会替换为任意长度的任意字符字符串,包括零,而在 Awk 中,*
只会匹配前一个字符或表达式的零次或多次重复。例如,"a*
" 会匹配 "a"、"aa"、"aaa" 等。这意味着 ".*" 会匹配任何字符字符串。作为一个更复杂的示例,
/(ab|c)*/
这会匹配 "ab"、"abab"、"ababab"、"c"、"cc"、"ccc",甚至 "abc"、"ababc"、"cabcababc",或任何其他类似的组合。
还有其他字符允许匹配重复的字符。?
匹配前一个正则表达式的正好零次或一次出现,而 +
匹配前一个正则表达式的 一次或多次出现。例如
/^[+-]?[0-9]+$/
这会匹配任何只包含(可能带符号的)整数的 行。这是一个有点令人困惑的例子,将其分解成部分是有帮助的
^
在行的开头查找字符串。[+-]?
指定数字可能的 "+" 或 "-" 符号。[0-9]+
指定至少一位数字 "0" 到 "9"。$
指定行以数字结尾。
虽然这种语法由 Single Unix Specification 定义,但许多 awk 没有实现此功能。在 GNU Awk 4.0 之前的版本中,你需要—posix 或—re-interval 选项来启用它。
如果要将正则表达式匹配特定次数,可以使用花括号 ({}
)。例如
/f[eo]{2}t/
这会匹配 "foot" 或 "feet"。
要指定数字为最小值,请在后面加上逗号。
/[0-9]{3,}/
这会匹配至少三位数的数字。这是编写以下代码的更简单的方法
/[0-9][0-9][0-9]+/
可以在花括号中放置两个用逗号分隔的数字来指定一个范围。
/^[0-9]{4,7}$/
这会匹配包含 4 位、5 位、6 位或 7 位数字的行。数字过多或不足,则不会匹配。
除非你已经熟悉正则表达式,否则你应该尝试编写一些自己的正则表达式。为了查看你是否写对了,可以编写一个简单的 Awk 程序来打印任何匹配表达式的行,并测试它。
- 编写一个正则表达式来匹配邮政编码。美国邮政编码由 5 位数字和可选的连字符以及另外 4 位数字组成。
- 编写一个正则表达式来匹配任何数字,包括可选的小数点后跟更多数字。
- 编写一个正则表达式来查找电子邮件地址。查找有效的字符(字母、数字、点和下划线),后跟 "@",然后是更多有效的字符,至少包含一个点。
- 编写一个正则表达式来匹配电话号码。它应该处理区号、分机号,以及可选的连字符和括号来对数字进行分组。确保它不会匹配过长或过短的电话号码。
在下一页中,你将学习其他类型的搜索模式。