如何使用Linux grep命令
了解在文件中搜索信息的基础知识,然后下载我们的备忘单以获取 grep 和 regex 的快速参考指南。
经典 Unix 命令之一是全局正则表达式打印 (grep) 命令,由 Ken Thompson 于 1974 年开发。它在计算中如此普遍,以至于经常用作动词(“grepping through a file”),并且根据您的受众的极客程度,它也非常适合现实世界的场景。 (例如,“我必须 grep 我的记忆库才能回忆起该信息。”)简而言之,grep 是一种在文件中搜索特定字符模式的方法。如果这听起来像任何文字处理程序或文本编辑器中可用的现代查找功能,那么您已经体验过 grep 对计算行业的影响。
grep 不仅仅是一个被现代技术取代的古怪的旧命令,它的真正力量在于两个方面:
- Grep 在终端中工作并处理数据流,因此您可以将其合并到复杂的流程中。您不仅可以在文本文件中查找某个单词,还可以在其中查找单词。您可以提取单词,将其发送到另一个命令,等等。
- Grep 使用正则表达式来提供灵活的搜索功能。
学习 grep 命令很容易,但需要一些练习。本文向您介绍了我认为最有用的一些功能。
[下载我们的免费 grep 备忘单]
安装 grep
如果您使用的是 Linux,则已经安装了 grep。
在 macOS 上,您有 BSD 版本的 grep。这与 GNU 版本略有不同,因此如果您想完全按照本文进行操作,请从 Homebrew 或 MacPorts 等项目安装 GNU grep。
基本 grep
基本的 grep 语法始终相同。您向 grep
命令提供一个模式和一个您希望其搜索的文件。作为回报,它会将每一行与匹配项打印到您的终端。
$ grep gnu gpl-3.0.txt
along with this program. If not, see <http://www.gnu.org/licenses/>.
<http://www.gnu.org/licenses/>.
<http://www.gnu.org/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...]
<http://www.gnu.org/licenses/>.
<http://www.gnu.org/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 处理数据的方式,因此我可以将它们通过管道传输到 curl
中,而不是将 URL 打印到我的终端:
$ grep --only-matching http\:\/\/.*pdf \
example.html | curl --remote-name
这会下载每个文件,并根据其远程文件名将其保存到我的硬盘上。
我在这个例子中的搜索模式可能看起来很神秘。这是因为它使用正则表达式,这是一种“通配符”语言,在广泛搜索大量文本时特别有用。
正则表达式
没有人认为正则表达式(简称“regex”)很简单。然而,我发现它的声誉往往比应有的要差。诚然,人们有可能对正则表达式有点太聪明,直到它变得难以阅读且宽泛以致于它自身折叠起来,但您不必过度使用正则表达式。下面简单介绍一下我使用正则表达式的方式。
首先,创建一个名为 example.txt
的文件并在其中输入以下文本:
Albania
Algeria
Canada
0
1
3
11
正则表达式最基本的元素是不起眼的 .
字符。它代表单个字符。
$ 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 备忘单!