Linux 中的 Grep 命令是什么? 为什么使用它以及它是如何工作的?

如果您使用 Linux 进行日常工作或开发和部署软件,那么您一定遇到过 grep 命令。

在这篇解释性文章中,我将告诉你什么是 grep 命令以及它是如何工作的。

什么是grep?

Grep 是 Unix 和 Linux 系统中的命令行实用程序。 它用于在给定文件的内容中查找搜索模式。

凭借其不同寻常的名称,您可能已经猜到 grep 是一个首字母缩略词。 这至少部分正确,但这取决于你问谁。

根据可靠消息来源,该名称实际上源自 UNIX 文本编辑器中的一个命令,称为 . 其中,输入 g/re/p 对正则表达式 (re) 执行全局 (g) 搜索,然后打印 (p) 任何匹配的行。

grep 命令执行 g/re/p 命令在编辑器中执行的操作。 它对正则表达式执行全局研究并打印它。 搜索大文件要快得多。

这是官方的叙述,但您也可能看到它被描述为 G大叶 R常规的 表达(处理器 | 亚瑟 | 打印机)。 说实话,它做到了所有这些。

创建 grep 背后的有趣故事

肯汤普森 对计算机科学做出了令人难以置信的贡献。 他帮助创建了 Unix,推广了其模块化方法,并编写了许多程序,包括 grep。

Thompson 构建了 grep 来帮助他的一位同事贝尔实验室. 这位科学家的目标是检查语言模式以确定联邦党人文集的作者(包括亚历山大·汉密尔顿)。 这份广泛的工作是为捍卫美国宪法而起草的 85 篇匿名文章和论文的集合。 但由于这些文章是匿名的,科学家试图根据语言模式识别作者。

由于当时的硬件限制,最初的 Unix 文本编辑器 ed(也是由 Thompson 创建的)无法搜索如此大量的文本。 因此,Thompson 将搜索功能转变为独立的实用程序,独立于 ed 编辑器。

如果你仔细想想,这意味着 Alexander Hamilton 在技术上帮助创建了 grep。 随时与您的朋友分享这个有趣的事实 汉密尔顿 观看派对。 ?

什么是正则表达式?

正则表达式(或正则表达式)可以被认为类似于搜索查询。 正则表达式用于识别、匹配或以其他方式管理文本。

不过,正则表达式的功能远不止关键字搜索。 它可以用来找到任何可以想象的模式。 使用元字符可以更容易地找到模式。 这些特殊字符使这个搜索工具更加强大。

需要注意的是,grep 只是一种使用正则表达式的工具。 各种工具都有类似的功能,但元字符和语法可能会有所不同。 这意味着了解特定正则表达式处理器的规则很重要。

一个实用的 example of grep:匹配电话号码

这个工具对于新手和有经验的 Linux 用户来说都可能是令人生畏的。 不幸的是,即使是像电话号码这样相对简单的模式也会导致看起来“吓人”的正则表达式字符串。

我想向你保证,当你看到这样的表情时,没有必要惊慌。 一旦您熟悉了正则表达式的基础知识,它就可以为您的计算打开一个充满可能性的新世界。

文化笔记: 这 example 电话号码使用美国 (NANP) 约定。 这些是 10 位 ID,分为区号(3 位)和唯一的 7 位组合,其中前 3 位对应于中央电信局(称为前缀),后 4 位称为线路数字。 所以模式是AAA-PPP-LLLL。

我创建了一个名为 phone.txt 并写下同一电话号码的 4 个常见变体。 无论格式如何,我都将使用 grep 来识别数字模式。

我还添加了一行不符合用作控件的表达式。 最后一行 555!123!1234 不是标准电话号码模式,不会由 grep 表达式返回。

的内容 phone.txt 文件是:

[email protected]:~$ cat phone.txt 
5551231234
555 123 1234
555-123-1234
(555)-123-1234
555!123!1234

为了“grep”电话号码,我将使用元字符编写我的正则表达式来隔离相关数据并忽略我不需要的数据。

完整的命令将如下所示:

[email protected]:~$ grep '(([0-9]{3})|[0-9]{3})[ -]?[0-9]{3}[ -]?[0-9]{4}' phone.txt

看起来有点激烈,对吧? 让我们把它分解成块,以便更好地了解正在发生的事情。

了解正则表达式,一次一段

首先,让我们分离在电话号码中查找“区号”的 RegEx 部分。

类似的模式也被部分重复以获得其余数字。 需要注意的是,区号有时会封装在括号中,因此您需要使用此处的表达式来说明这一点。

整个区号部分的逻辑被封装在一组转义的圆括号中。 你可以看到我的代码以 ( 并以 ).

当您使用方括号时 [0-9],你让 grep 知道你正在寻找一个介于 0 和 9 之间的数字。同样,你可以使用 [a-z] 匹配字母表中的字母。

大括号中的数字 {3}表示方括号中的项目恰好匹配了 3 次。

还在迷茫吗? 不要压力过大。 你要看看这个 example 以多种方式让您有信心向前迈进。

让我们试着看看伪代码中区号部分的逻辑。 我已经隔离了表达式的每个部分。

区号正则表达式的伪代码

  • (
  • (三位数字)
  • |
  • 三位数字
  • )

希望像这样看到它会使正则表达式更简单。 用简单的语言,您正在寻找 3 位数字。 每个数字可以是 0-9,并且可能有 或者 区号周围可能没有括号。

然后,在我们第一部分的末尾有一个奇怪的部分。

  • [ -]?

这是什么意思? 这 ? 符号表示“匹配零个或前面的字符之一”。 在这里,这是指我们方括号中的内容 [ -].

换句话说,数字后面可能有也可能没有连字符。

区号

现在,让我们用实际代码重新构建相同的块。 然后,我将添加表达式的其他部分。

  • (
  • ([0-9]{3})
  • |
  • [0-9]{3}
  • )
  • [ -]?

字首

要完成电话号码模式,您只需重新使用一些现有代码即可。

[0-9]{3}[ -]?

您不必担心前缀周围的括号,但您仍然可能有也可能没有 - 在电话号码的前缀和线路数字之间。

行号

电话号码的最后一部分不需要我们查找任何其他字符,但您需要更新表达式以反映多余的数字。

[0-9]{4}

就是这样。 现在让我们确保表达式包含在引号中以最大程度地减少意外行为。

这是完整的表达方式

[email protected]:~$ grep '(([0-9]{3})|[0-9]{3})[ -]?[0-9]{3}[ -]?[0-9]{4}' phone.txt
Grep电话号码Regex成功返回

您可以看到结果以颜色突出显示。 这可能不是 Linux 发行版的默认行为。

奖金提示

如果您希望突出显示结果,可以添加 --color=auto 听从你的命令。 您还可以将其作为别名添加到您的 shell 配置文件中,以便每次键入 grep 它作为 grep --color=auto.

我希望您现在对 grep 命令有更好的理解。 我只展示了一个 example 解释事情。 如果有兴趣,您可以查看这篇文章以获取更多关于 grep 命令的实际示例。

请通过发表评论提供您对文章的建议。