Grep和正则表达式:如何有效使用它们?

如果您使用linux一段时间了,您应该已经了解grep – global regular expression print,这是一个可以用于搜索文件和目录的文本处理工具。对于linux高级用户来说,它非常有用。然而,如果不使用正则表达式,使用它可能会限制其功能。

但是什么是正则表达式?

正则表达式是可以用于改进grep搜索功能的正则表达式。正则表达式按定义是高级的输出过滤模式。通过实践,您可以有效地使用正则表达式,因为您也可以将其与其他linux命令一起使用。

在我们的教程中,我们将学习如何有效地使用grep和正则表达式。

先决条件

使用带有正则表达式的grep需要良好的linux知识。如果您是初学者,那么请查看我们的linux指南

您还需要访问运行linux操作系统的笔记本电脑或计算机。您可以使用任何您喜欢的linux发行版。而且,如果您有一台windows机器,您仍然可以使用带有wsl2的linux。请查看我们对此的详细说明here

访问命令行/终端允许您运行我们的grep / regex教程中提供的所有命令。

此外,您还需要访问一个文本文件(或多个),您需要在其中运行示例。我使用chatgpt生成了一堆文本,让它写一些关于技术的内容。我使用的提示如下。

“在技术方面生成400个字。它应该包括大部分技术。此外,请确保在文本中重复使用技术名称。”

生成文本后,我将其复制并保存在tech.txt文件中,我们将在整个教程中使用它。

最后,必须具备对grep命令的基本理解。您可以查看16个grep命令示例来更新您的知识。我们还将简要介绍grep命令,以帮助您入门。

grep命令的语法和示例

grep 命令的语法很简单。

$ grep -options [regex/pattern] [files]

正如您所注意到的,它期望一个模式和您要运行该命令的文件列表。

有很多可用的grep选项可以修改其功能。这些选项包括:

  • – i: 忽略大小写
  • -r: 执行递归搜索
  • -w: 仅查找整个单词
  • -v: 显示所有不匹配的行
  • -n: 显示所有匹配行的行号
  • -l: 打印文件名
  • –color: 彩色结果输出
  • -c: 显示所使用模式的匹配计数

#1. 查找整个单词

您需要在grep中使用-w参数进行整个单词搜索。通过使用它,您可以绕过与给定模式匹配的任何字符串。

$ grep -w ‘tech|5g’ tech.txt

如您所见,该命令的输出结果是在整个文本中搜索了两个单词“5g”和“tech”。然后,它用红色标记它们。

在这里,|管道符号被转义,以便grep不将其处理为元字符。

#2. 大小写不敏感的搜索

要进行大小写不敏感的搜索,请使用带有-i参数的grep命令。

$ grep -i ‘tech’ tech.txt

该命令搜索任何不区分大小写的“tech”字符串的实例,无论是完整的单词还是其中的一部分。

#3. 非匹配行搜索

要显示不包含给定模式的所有行,需要使用-v参数。

$ grep -v ‘tech’ tech.txt

输出显示所有不包含单词“tech”的行。您还将看到空行。这些行是段落之后的行。

#4. 递归搜索

要进行递归搜索,请使用带有-r参数的grep命令。

$ grep -r ‘error|warning’ /var/log/*.log
#output

/var/log/bootstrap.log:2023-01-03 21:40:18 url:http://ftpmaster.internal/ubuntu/pool/main/libg/libgpg-error/libgpg-erro 0_1.43-3_amd64.deb [69684/69684] -> "/build/chroot//var/cache/apt/archives/partial/libgpg-error0_1.43-3_amd64.deb" [1]

/var/log/bootstrap.log:dpkg: warning: parsing file '/var/lib/dpkg/status' near line 5 package 'dpkg':

/var/log/bootstrap.log:dpkg: warning: parsing file '/var/lib/dpkg/status' near line 5 package 'dpkg':

/var/log/bootstrap.log:dpkg: warning: parsing file '/var/lib/dpkg/status' near line 24 package 'dpkg':

/var/log/bootstrap.log:dpkg: warning: parsing file '/var/lib/dpkg/status' near line 24 package 'dpkg':

/var/log/bootstrap.log:dpkg: warning: ignoring pre-dependency problem!

grep命令在/var/log目录中递归搜索两个词“error”和“warning”。这是一个方便的命令,可以了解日志文件中的任何警告和错误。

grep和正则表达式:定义及示例

由于我们正在使用正则表达式,因此您需要知道正则表达式提供三种语法选项。其中包括:

  • 基本正则表达式(bre)
  • 扩展正则表达式(ere)
  • perl兼容正则表达式(pcre)

grep命令使用bre作为默认选项。因此,如果要使用其他正则表达式模式,您需要提及它们。grep命令还按照原样处理元字符。因此,如果您使用诸如?、+、)之类的元字符,则需要使用反斜杠()命令对它们进行转义。

grep与正则表达式的语法如下。

$ grep [regex] [filenames]

让我们通过以下示例来看看grep和正则表达式的运作方式。

#1. 文字匹配

要进行文字匹配,您需要提供一个字符串作为正则表达式。毕竟,一个单词也是一个正则表达式。

$ grep "technologies" tech.txt

同样,您还可以使用精确匹配来查找当前用户。要这样做,请运行:

$ grep bash /etc/passwd
#输出

root:x:0:0:root:/root:/bin/bash

nitt:x:1000:1000:,,,:/home/nitt:/bin/bash

这将显示可以访问bash的用户。

#2. 锚点匹配

锚点匹配是一种使用特殊字符进行高级搜索的有用技术。在正则表达式中,有不同的锚点字符,您可以使用它们来表示文本中的特定位置。这些包括:

  • ^’ 尖号符号:尖号符号匹配输入字符串或行的开头,并查找一个空字符串。
  • $’ 美元符号:美元符号匹配输入字符串或行的结尾,并查找一个空字符串。

另外两个锚点匹配字符包括‘ b’字边界和‘ b’非字边界。

  • ‘ b’ 字边界:使用 b,您可以断言一个单词和一个非单词字符之间的位置。简单来说,它可以让您匹配完整的单词。这样,您可以避免部分匹配。您还可以使用它来替换单词或计算字符串中单词出现的次数。
  • b 非字边界:它与正则表达式中的b字边界相反,它断言的是一个位置,该位置不在两个单词或非单词字符之间。

让我们通过示例来更清楚。

$ grep ‘^from’ tech.txt

使用尖号需要以正确的大小写输入单词或模式。这是因为它区分大小写。因此,如果运行以下命令,它将不会返回任何结果。

$ grep ‘^from’ tech.txt

同样,您还可以使用$符号找到与给定模式、字符串或单词匹配的句子。

$ grep ‘technology.$' tech.txt

您还可以同时使用^和$符号。让我们看下面的例子。

$ grep “^from | technology.$” tech.txt

如您所见,输出包含以“from”开头的句子和以“technology”结尾的句子。

#3. 分组

如果您想同时搜索多个模式,您需要使用分组。它可以帮助您创建包含字符和模式的小组,您可以将其视为单个单元。例如,您可以创建一个包含术语‘t’、‘e’、‘c’、‘h’的组(tech)。

为了更清楚地了解,请看一个示例。

$ grep 'technol(ogy)?' tech.txt

通过分组,您可以匹配重复的模式、捕获组,并搜索替代项。

使用分组进行替代搜索

让我们看一个替代搜索的示例。

$ grep "(tech|technology)" tech.txt

如果你想在一个字符串上执行搜索操作,那么你需要用管道符传递它。让我们看下面的例子。

$ echo "tech technological technologies technical" | grep "(tech|technology)"
#output

"tech technological technologies technical"

捕获组、非捕获组和重复模式

那捕获组和非捕获组呢?

你需要在正则表达式中创建一个组,并将其传递给字符串或文件以进行捕获组。

$ echo 'tech655 tech655nical technologies655 tech655-oriented 655' | grep "(tech)(655)"
#output

tech655 tech655nical technologies655 tech655-oriented 655

至于非捕获组,你需要在括号中使用 ?:。

最后,我们有重复的模式。你需要修改正则表达式以检查重复的模式。

$ echo 'teach tech ttrial tttechno attest' | grep '(t+)'
#output

'teach tech ttrial tttechno attest'

在这里,正则表达式查找一个或多个“t”字符的实例。

#4. 字符类

使用字符类,你可以轻松编写正则表达式。这些字符类使用方括号。一些众所周知的字符类包括:

  • [:digit:] – 0到9的数字
  • [:alpha:] – 字母字符
  • [:alnum:] – 字母数字字符
  • [:lower:] – 小写字母
  • [:upper:] – 大写字母
  • [:xdigit:] – 十六进制数字,包括0-9、a-f、a-f
  • [:blank:] – 空白字符,如制表符或空格

等等!

让我们看看其中一些的示例。

$ grep [[:digit]] tech.txt
$ grep [[:alpha:]] tech.txt
$ grep [[:xdigit:]] tech.txt

#5. 量词

量词是元字符,是正则表达式的核心。它们允许你匹配确切的出现次数。让我们看看它们。

  • * → 零个或多个匹配
  • + → 一个或多个匹配
  • ? → 零个或一个匹配
  • {x} → x个匹配
  • {x, } → x个或更多匹配
  • {x,z} → 从x到z个匹配
  • {, z} → 最多z个匹配
$ echo 'teach tech ttrial tttechno attest' | grep -e 't+'
#output

'teach tech ttrial tttechno attest'

在这里,它搜索一个或多个匹配项的t字符实例。在这里,-e代表扩展的正则表达式(我们稍后会讨论)。

#6. 扩展的正则表达式

如果您不想在正则表达式模式中添加转义字符,您必须使用扩展的正则表达式。它消除了添加转义字符的需要。为此,您需要使用-e标志。

$ grep -e 'in+ovation' tech.txt

#7. 使用pcre进行复杂搜索

pcre(perl兼容正则表达式)让您可以做比编写基本表达式更多的事情。例如,您可以编写“d”,它表示[0-9]。

例如,您可以使用pcre搜索电子邮件地址。

echo "contact me at [email protected]" | grep -p "b[a-za-z0-9._%+-]+@[a-za-z0-9.-]+.[a-za-z]{2,}b"
#output

contact me at [email protected]

在这里,pcre确保模式匹配。类似地,您还可以使用pcre模式来检查日期模式。

$ echo "the sparkain site launched on 2023-07-29" | grep -p "bd{4}-d{2}-d{2}b"
#output

the sparkain site launched on 2023-07-29

该命令找到了以yyyy-mm-dd格式的日期。您可以修改它以匹配其他日期格式。

#8. 选择

如果您想要备用匹配项,可以使用转义的竖线字符(|)。

$ grep -l ‘warning|error’ /var/log/*.log
#output

/var/log/alternatives.log

/var/log/bootstrap.log

/var/log/dpkg.log

/var/log/fontconfig.log

/var/log/ubuntu-advantage.log

/var/log/upgrade-policy-changed.log

输出列出了包含“warning”或“error”的文件名。

最后的话

这就是我们的grep和正则表达式指南的结束。您可以广泛地使用grep与正则表达式来精确搜索。正确使用可以节省大量时间,并有助于自动化许多任务,特别是如果您将它们用于编写脚本或通过文本进行搜索。

接下来,请查看常见的linux面试问题和答案

类似文章