如何使用 Linux grep 命令

学习在文件中搜索信息的基础知识,然后下载我们的速查表,作为 grep 和正则表达式的快速参考指南。
119 位读者喜欢这个。
Why the operating system matters even more in 2017

互联网档案馆书籍图片。由 Opensource.com 修改。CC BY-SA 4.0

Ken Thompson 在 1974 年开发的经典 Unix 命令之一是全局正则表达式打印 (grep) 命令。它在计算领域非常普遍,经常被用作动词(“grepping through a file”),而且,取决于你的听众的极客程度,它也很适合现实场景。(例如,“我必须 grep 我的记忆库才能回忆起该信息。”)简而言之,grep 是一种在文件中搜索特定字符模式的方法。如果这听起来像任何文字处理器或文本编辑器中提供的现代查找功能,那么你已经体验过 grep 对计算行业的影响。

grep 的真正力量远不仅仅是被现代技术取代的古老命令,它的真正力量在于两个方面:

  • Grep 在终端中工作并对数据流进行操作,因此你可以将其合并到复杂的过程中。你不仅可以查找文本文件中的单词;还可以提取该单词,将其发送到另一个命令等等。
  • Grep 使用正则表达式来提供灵活的搜索功能。

学习 grep 命令很容易,尽管它确实需要一些练习。 本文向你介绍了我发现最有用的某些功能。

[下载我们的免费 grep 速查表]

安装 grep

如果你正在使用 Linux,你已经安装了 grep。

在 macOS 上,你拥有 BSD 版本的 grep。 这与 GNU 版本略有不同,因此,如果你想完全按照本文进行操作,请从像 HomebrewMacPorts 这样的项目中安装 GNU grep。

基本 grep

基本的 grep 语法始终相同。你向 grep 命令提供一个模式和你希望它搜索的文件。作为回报,它会将每行匹配项打印到你的终端。

$ grep gnu gpl-3.0.txt
    along with this program.  If not, see <https://gnu.ac.cn/licenses/>.
<https://gnu.ac.cn/licenses/>.
<https://gnu.ac.cn/philosophy/why-not-lgpl.html>.

默认情况下,grep 命令区分大小写,因此“gnu”与“GNU”或“Gnu”不同。你可以使用 --ignore-case 选项使其忽略大小写。

$ grep --ignore-case gnu gpl-3.0.txt
                    GNU GENERAL PUBLIC LICENSE
  The GNU General Public License is a free, copyleft license for
the GNU General Public License is intended to guarantee your freedom to
GNU General Public License for most of our software; it applies also to
[...16 more results...]
<https://gnu.ac.cn/licenses/>.
<https://gnu.ac.cn/philosophy/why-not-lgpl.html>.

你还可以使用 --invert-match 选项使 grep 命令返回没有匹配的所有行

$ grep --invert-match \
--ignore-case gnu gpl-3.0.txt
                      Version 3, 29 June 2007

 Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
[...648 lines...]
Public License instead of this License.  But first, please read

管道

能够查找文件中的文本非常有用,但 POSIX 的真正力量在于它能够通过“管道”将命令链接在一起。 我发现我对 grep 的最佳使用是将其与其他工具(如 cut、tr 或 curl)结合使用。

例如,假设我有一个文件,其中列出了一些我想下载的技术论文。我可以打开该文件并手动单击每个链接,然后单击 Firefox 选项以将每个文件保存到我的硬盘驱动器,但这会花费大量时间和点击。 相反,我可以 grep 文件中的链接,并通过使用 --only-matching 选项来仅打印匹配的字符串

$ grep --only-matching http\:\/\/.*pdf example.html
http://example.com/linux_whitepaper.pdf
http://example.com/bsd_whitepaper.pdf
http://example.com/important_security_topic.pdf

输出是一个 URL 列表,每个 URL 位于一行上。这非常适合 Bash 处理数据的方式,因此与其将 URL 打印到我的终端,不如将它们通过管道传递到 curl

$ grep --only-matching http\:\/\/.*pdf \
example.html | curl --remote-name

这会下载每个文件,并根据其远程文件名将其保存到我的硬盘驱动器上。

在此示例中,我的搜索模式可能看起来很神秘。 这是因为它使用正则表达式,这是一种“通配符”语言,在广泛搜索大量文本时特别有用。

正则表达式

没有人认为正则表达式(简称“regex”)容易。 但是,我发现它的声誉通常比它应得的要差。 诚然,人们有可能在使用正则表达式时变得过于聪明,直到它变得难以阅读且过于宽泛,以至于它会自我折叠,但是你不必过度使用正则表达式。 这是我对正则表达式的简要介绍,它是我使用它的方式。

首先,创建一个名为 example.txt 的文件,并将此文本输入其中

Albania
Algeria
Canada
0
1
3
11

正则表达式最基本的元素是 humble . 字符。 它代表一个字符。

$ grep Can.da example.txt
Canada

模式 Can.da 成功返回了 Canada,因为 . 字符代表任何一个字符。

可以使用以下表示法修改 . 通配符以表示多个字符

  • ? 匹配前一项零次或一次
  • * 匹配前一项零次或多次
  • + 匹配前一项一次或多次
  • {4} 匹配前一项四次(或你在括号中输入的任何数字)

有了这些知识,你可以在整个下午在 example.txt 上练习正则表达式,看看你会想到哪些有趣的组合。 有些不起作用,有些会起作用。 重要的是分析结果,以便你了解原因。

高级正则表达式需要 --extended-regexp-E 选项。

例如,这无法返回任何国家/地区

$ grep -E A.a example.txt

它失败的原因是 . 字符只能匹配单个字符,除非你对其进行升级。 使用 * 字符,你可以告诉 grep 匹配单个字符零次或根据需要多次,直到到达单词结尾。 因为你知道你正在处理的列表,所以你知道在这种情况下零次是无用的。 此列表中绝对没有三个字母的国家/地区名称。 因此,你可以使用 + 至少匹配一次单个字符,然后根据需要再次匹配多次,直到单词结尾

$ grep -E A.+a example.txt
Albania
Algeria

你可以使用方括号来提供字母列表

$ grep -E [AC].+a example.txt
Albania
Algeria
Canada

这也适用于数字。 结果可能会让你感到惊讶

$ grep [1-9] example.txt
1
3
11

你是否惊讶于在搜索数字 1 到 9 时看到 11?

如果你将 13 添加到你的列表中会发生什么?

返回这些数字是因为它们包含 1,1 是要匹配的数字列表中的一个。

如你所见,正则表达式有点像一个难题,但是通过实验和实践,你可以熟悉它并使用它来改进你通过数据进行 grep 的方式。

下载速查表

grep 命令的选项比我在本文中演示的要多得多。 有一些选项可以更好地格式化结果,列出包含匹配项的文件和行号,通过打印匹配项周围的行来为结果提供上下文,等等。 如果你正在学习 grep,或者你只是发现自己经常使用它并求助于搜索其 info 页面,那么下载我们的速查表会对你有所帮助。 速查表使用短选项(例如,-v 而不是 --invert-matching)作为让你熟悉常用 grep 简写的一种方式。 它还包含一个正则表达式部分,以帮助你记住最常见的正则表达式代码。 立即下载 grep 速查表!

接下来要阅读什么
标签
Seth Kenlon
Seth Kenlon 是一名 UNIX 极客、自由文化倡导者、独立多媒体艺术家和 D&D 爱好者。 他曾在电影和计算行业工作,通常同时从事这两项工作。

9 评论

不错的文章,但我不知道有人使用 --ignore-case, --invert-match 等。 -i, -v 等更容易键入。

感谢您的阅读!

是的,短选项更容易键入,但在记录和编写脚本时不太清楚。 长选项是自描述的,并且了解它们通常有助于记住短选项。 在记录时,我使用长选项以提高清晰度,并提供短选项作为快速替代方法。 在编写脚本时,我使用长选项是因为它描述了命令的意图。

回复 ,作者:MartyMonroe

由于 grep 返回信息的方式,它可以告诉你如何在文本文件中构建信息,以便使用 grep 进行最有效的检索。
你可以通过使用 kwrite 加载一个文件,并使用“查找/替换”的“正则表达式”选项,然后点击“查找全部”来查看正则表达式条目匹配的内容来练习正则表达式。

`--only-matching` - 太棒了,真是太棒了。

感谢您这篇有用的文章和速查表。 顺便提一下,在我的系统(grep gnu v3.6, slackware)中,我还必须使用扩展正则表达式标志 -E 才能使模式生效。

非常好的观点,谢谢。 我试图在我的 RHEL 和我的 Slackware 机器上测试所有命令,但我可能忽略了这一个。 我已经更新了文章,添加了关于扩展正则表达式选项的说明。

回复 ,作者:anestis

不错的文章,但有些小问题

"{4} 匹配前面的项目最多四次(或你在花括号中输入的任何数字)"

它精确匹配 4 次。 "a{4}" 将匹配 "aaaa",但不会匹配 "aaa"

"grep [A,C].+a example.txt"

这句话本身没有错,但具有误导性。 它暗示如果你想查找 "A" 或 "C",那么 [A,C] 就是你想要的。 这实际上是在寻找 "A" 或 "," 或 "C"。

Creative Commons License本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。
© . All rights reserved.