简介
<$>[注]
注意: 有关如何使用grep
和正则表达式在Linux中搜索文本模式的更详细概述,请访问此配套教程。
<$>
作为系统管理员、开发人员、QA工程师、支持工程师等,人们需要从文件中找到特定的模式,例如属于某个范围或时间戳范围的一组IP地址或一组域或子域名。用户可能还需要查找以特定方式拼写的单词或在文件中查找可能的打字错误。这就是正则表达式发挥作用的地方。
正则表达式是匹配模式(有时不匹配模式)的模板。它们提供了一种描述和解析文本的方法。本教程将深入了解正则表达式,而不涉及任何语言的特殊性。我们将简单地使用egrep来解释概念。
正则表达式
正则表达式包含两种类型的字符:
- 常规文字字符和
- 元字符
这些元字符是赋予正则表达式力量的字符。
考虑下面的Country.txt文件,其中第一列是国家名称,第二列是国家的人口,第三列是大陆。
1$ cat country.txt
2India,1014003817,Asia
3Italy,57634327,Europe
4Yemen,1184300,Asia
5Argentina,36955182,Latin America
6Brazil,172860370,Latin America
7Cameroon,15421937,Africa
8Japan,126549976,Asia
锚定元字符
我们将讨论的第一组元字符是**^** 和** $** 。** ^** 和** $** 分别匹配模式的开始和结束,称为_锚元字符_。
为了找出所有国家名称以I开头的国家的名称,我们使用表达式:
1$ egrep '^I' country.txt
2India,1014003817,Asia
3Italy,57634327,Europe
或者找出所有洲名以e结尾的国家,我们可以:
1$ egrep 'e$' country.txt
2Italy,57634327,Europe
下一个元字符是点(.),它匹配any_one字符_。要匹配国家名称长度正好为5个字符的所有行,请执行以下操作:
1$ egrep '^.....,' country.txt
2India,1014003817,Asia
3Italy,57634327,Europe
4Yemen,1184300,Asia
5Japan,126549976,Asia
查找国家名称以I或J开头且国家名称长度为5个字符的所有行如何?
1$ egrep '^[IJ]....,' country.txt
2India,1014003817,Asia
3Italy,57634327,Europe
4Japan,126549976,Asia
[.]称为_Character Set_或_Character Class_。在一个字符集中,只有一个给定的字符是匹配的。
字符集内的^表示否定该字符集。以下示例将匹配五个字符长但不以I或J开头的国家/地区名称。
1$ egrep '^[^IJ]....,' country.txt
2Yemen,1184300,Asia
超元字符和交替
要匹配包含亚洲或非洲的所有行:
1$ egrep 'Asia|Africa' country.txt
2India,1014003817,Asia
3Yemen,1184300,Asia
4Cameroon,15421937,Africa
5Japan,126549976,Asia
这也可以通过取_A_和_a_COMMON来实现。
1$ egrep 'A(si|fric)a' country.txt
2India,1014003817,Asia
3Yemen,1184300,Asia
4Cameroon,15421937,Africa
5Japan,126549976,Asia
量词
与其写作,不如
1$ egrep '^[IJ]....,' country.txt
我们可以写
1$ egrep '^[IJ].{4},' country.txt
其中,{}称为_量词_。他们决定在他们之前的角色应该出现多少次。
我们也可以给出一个范围:
1$ egrep '^[IJ].{4,6},' country.txt
2India,1014003817,Asia
3Italy,57634327,Europe
4Japan,126549976,Asia
这将匹配以I或J开头且后面有4到6个字符的国家/地区名称。
量词有一些快捷方式。例如,
{0,1}等同于?
1$ egrep '^ab{0,1}c$' filename
与之相同
1$ egrep '^ab?c' filename
{0,}等同于*
1$ egrep '^ab{0,}c$' filename
与之相同
1$ egrep '^ab*c' filename
{1,}等同于+
1$ egrep '^ab{1,}c$' filename
与之相同
1$ egrep '^ab+c' filename
让我们看一些与我们到目前为止所看到的表达方式有关的例子。在这里,我们不是从文件搜索,而是从标准输入搜索。我们使用的诀窍是,我们知道grep(或egrep)搜索一个模式,如果找到一个模式,则显示包含该模式的整行。
我们想找出这个句子的所有可能的拼写方法。
表达式将为:
1$ egrep 'the gr[ea]y colou?r suit was his favou?rite'
2the grey color suit was his favourite
3the grey color suit was his favourite
4
5the gray colour suit was his favorite
6the gray colour suit was his favorite
查看上面的表达式,我们可以看到:
- GREAY可以拼写为GREAD或GREAD
- COLOR可以写成COLOR或COLOR,这意味着u是可选的,所以我们使用u?
- 同样,最爱或最爱也可以写成Favou?
如何匹配美国邮政编码?
1$ egrep '^[0-9]{5}(-[0-9]{4})?$'
283456
383456
4
583456-
6
7834562
8
992456-1234
1092456-1234
11
1210344-2342-345
又一个匹配24小时时钟中所有有效时间的例子。
1$ egrep '^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]'
223:44:02
323:44:02
4
533:45:11
6
715:45:33
815:45:33
在上面的例子中,我们说过,如果小时的第一个数字是0或1,那么第二个数字将 可以是从0到9的任意数字。但如果第一个数字是2,则第二个数字的允许值是0、1、2或3。
词边界
写一个图案来匹配以颜色结尾的单词,以使单色、水彩、多彩等。 相匹配,但不是无色或五颜六色的。自己尝试这些例子,以熟悉它们:
1$ egrep 'color\>'
其次,要搭配无色和多彩,但不能单色、水彩、多彩等。
1$ egrep '\<color'
因此,为了匹配确切的单词颜色,我们这样做:
1$ egrep '\<color\>'
反向引用
假设我们想要匹配所有双类型的单词,比如_the_或_Being_,我们必须使用反向引用。反向引用是用来记忆模式的。
下面是一个例子:
1$ egrep "\<the\> \1"
或者一般的方式:
1$ egrep "\<(.*)\> \1"
上面的例子可以用来查找所有名字和姓氏相同的名字。如果有一个以上的括号,那么第二个,第三个,第四个等等可以用\2,\3,\4等引用。
_这只是对正则表达式的强大功能的介绍。