在 Linux 中使用 grep 搜索文本

CompTIACompTIABeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

引言

在本实验中,你将学习如何使用强大的 grep 命令在 Linux 系统中有效地搜索文件内的文本。你将从在单个和多个文件中搜索特定字符串开始,理解 grep 如何显示匹配的行以及在搜索多个位置时如何识别源文件。

在此基础上,你将探索更高级的功能来优化你的搜索。你将学习显示行号以提供上下文,使用 ^$ 等锚点来匹配行开头或结尾的模式,并利用基本和扩展正则表达式的功能来执行复杂且灵活的模式匹配。

使用 grep 在文件中执行基本搜索

在此步骤中,你将学习 grep 命令的基本用法,以在文件中执行基本搜索。grep (Global Regular Expression Print) 命令是一个强大的命令行工具,用于在一个或多个文件中搜索特定字符串或模式,并显示包含它的行。

grep 的基本语法是:grep PATTERN [FILE...]

让我们从一个简单的任务开始:在系统的用户数据库文件中查找关于我们当前用户 labex 的信息。这些信息存储在 /etc/passwd 文件中。

在你的终端中执行以下命令,以在 /etc/passwd 文件中查找包含字符串 labex 的所有行:

grep labex /etc/passwd

你应该会看到文件中包含你的用户名 labex 的输出行。

labex:x:5000:5000::/home/labex:/usr/bin/zsh

grep 命令还可以同时搜索多个文件。现在,我们将搜索三个重要的系统配置文件中的字符串 labex/etc/passwd/etc/shadow(存储安全用户账户信息)和 /etc/group(定义用户组)。

由于 /etc/shadow 文件包含敏感信息,你需要管理员权限才能读取它。你可以使用 sudo 命令以这些权限执行 greplabex 用户已配置为无需密码即可使用 sudo

执行以下命令以在所有三个文件中搜索 labex

sudo grep labex /etc/passwd /etc/shadow /etc/group

请注意,在搜索多个文件时,grep 会在每个匹配的行前面加上找到匹配项的文件名。

/etc/passwd:labex:x:5000:5000::/home/labex:/usr/bin/zsh
/etc/shadow:labex:$y$j9T$L6UYJUCu2XytrdFToEOw.1$yp2xAOVTbIPmbABMnS/xDsyce7xayU80JgIs3lrqw4B:20265:0:99999:7:::
/etc/group:sudo:x:27:labex
/etc/group:ssl-cert:x:121:labex
/etc/group:labex:x:5000:
/etc/group:public:x:5002:labex

这会显示这三个文件中所有与用户 labex 相关的行。

使用 -n 选项显示行号

在此步骤中,你将学习如何通过显示匹配项所在的行号来增强 grep 的输出。当你需要在大型文件中定位模式以进行编辑或进一步分析时,这尤其有用。-n 选项告诉 grep 在每个输出行前面加上它在输入文件中的对应行号。

让我们基于上一步的命令进行扩展。你搜索了三个系统文件中的用户 labex。现在,你将执行相同的搜索,但同时显示每个匹配项的行号。

-n 选项添加到你在上一步执行的命令中。请记住使用 sudo,因为你仍然在访问受限的 /etc/shadow 文件。

在你的终端中执行以下命令:

sudo grep -n labex /etc/passwd /etc/shadow /etc/group

你将看到与之前类似的输出,但现在每行前面都带有文件名和匹配发生的行号,它们之间用冒号分隔。

/etc/passwd:32:labex:x:5000:5000::/home/labex:/usr/bin/zsh
/etc/shadow:32:labex:$y$j9T$L6UYJUCu2XytrdFToEOw.1$yp2xAOVTbIPmbABMnS/xDsyce7xayU80JgIs3lrqw4B:20265:0:99999:7:::
/etc/group:21:sudo:x:27:labex
/etc/group:60:ssl-cert:x:121:labex
/etc/group:61:labex:x:5000:
/etc/group:62:public:x:5002:labex

注意输出中的数字,如 323221606162。这些就是行号。例如,字符串 labex/etc/passwd 的第 32 行和 /etc/shadow 的第 32 行被找到。这个简单的选项使 grep 成为一个更有效的工具,用于浏览和理解文件内容。

使用 ^ 和 $ 锚点匹配行位置

在此步骤中,你将通过学习使用锚点来提升你的 grep 技能。锚点是正则表达式中的特殊字符,它们不匹配字符本身,而是匹配行内的位置。这使你能够创建更具体、更强大的搜索模式。最常用的两个锚点是:

  • ^ (脱字符):匹配行的开头。
  • $ (美元符号):匹配行的结尾。

让我们通过 /etc/passwd 文件来了解它们的工作方式。

首先,考虑在 /etc/passwd 中搜索字符串 root

grep root /etc/passwd

你可能会在输出中得到多行,因为其他条目也可能包含字符串 "root"。

root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

现在,让我们进行优化。在 /etc/passwd 文件中,每条记录的第一个字段是用户名。要专门查找用户 root 的记录,你可以使用 ^ 将搜索锚定到行的开头。

执行以下命令。模式 ^root 告诉 grep 只匹配 root 开头的行。

grep ^root /etc/passwd

这次,输出更加精确,只显示了 root 用户的行。

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

接下来,让我们使用行尾锚点 $/etc/passwd 记录的最后一个字段指定了用户的默认登录 shell。我们可以用它来查找所有将 /bin/bash 作为其默认 shell 的用户。

模式 bash$ 将匹配 字符串 bash 结尾的任何行。

grep bash$ /etc/passwd

此命令将显示所有将 /bin/bash 指定为 shell 的用户条目。

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

(注意:如果系统上的其他用户也使用 bash 作为其默认 shell,你的输出可能会有所不同。)

通过使用 ^$ 锚点,你可以显著缩小搜索结果范围,以精确找到你想要的内容。

使用基本正则表达式匹配模式

在此步骤中,你将探索如何使用 grep 的基本正则表达式 (BRE) 来创建更灵活的搜索模式。在 BRE 中,某些字符被称为元字符,它们具有超越其字面值的特殊含义。这使你能够匹配模式,而不仅仅是固定的字符串。

我们将探讨两个基本的元字符:* (星号) 和 . (点)。

首先,让我们检查星号 (*)。这个元字符匹配其前面的字符零次或多次。要实际看到这一点,请执行以下命令。我们将模式用单引号 ('roo*') 括起来,以确保 shell 将其视为字面模式,而不是尝试将 * 扩展为文件通配符。

grep 'roo*' /etc/passwd

输出可能显示多行:

root:x:0:0:root:/root:/bin/bash
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
systemd-timesync:x:104:110:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
rtkit:x:108:113:RealtimeKit,,,:/proc:/usr/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin

让我们分析一下这个结果。模式 'roo*' 搜索包含 ro 后跟零个或多个 o 的行。

  • root 行匹配,因为它包含 roo (ro 后跟一个 o)。
  • proxy 行匹配,因为它在 "proxy" 中包含 ro (ro 后跟零个 o)。
  • systemd-timesync 行匹配,因为它在 "Synchronization" 中包含 ro
  • rtkit 行匹配,因为它在 "proc" 中包含 ro
  • operator 行匹配,因为它在 "operator" 和 "/root" 中都包含 ro

现在,让我们看看点 (.) 元字符。点匹配任何单个字符。执行以下命令以了解其行为有何不同:

grep 'ro.' /etc/passwd

这次,输出显示了几个匹配项:

root:x:0:0:root:/root:/bin/bash
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
systemd-timesync:x:104:110:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
rtkit:x:108:113:RealtimeKit,,,:/proc:/usr/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin

模式 'ro.' 搜索包含 ro 后跟正好一个任意字符的行。

  • root 行匹配,因为 ro 在 "root" 中后跟 o
  • proxy 行匹配,因为 ro 在 "proxy" 中后跟 x
  • systemd-timesync 行匹配,因为它在 "Synchronization" 中后跟 n
  • rtkit 行匹配,因为它在 "proc" 中后跟 c
  • operator 行匹配,因为它在 "operator" 和 "/root" 中后跟另一个字符。

通过比较输出,你可以清楚地看到正则表达式的强大之处。'roo*''ro.' 这两个模式都匹配了多行,展示了不同的元字符如何让你以不同的方式精细调整你的搜索。

使用扩展正则表达式进行复杂搜索

在此步骤中,你将学习使用扩展正则表达式 (ERE) 来执行更复杂、更强大的搜索。ERE 提供了比基本正则表达式 (BRE) 更丰富的元字符集。要启用 ERE,你可以使用 grep -E 命令或其传统别名 egrep。使用 grep -E 是更现代且推荐的方法。

首先,让我们探索量词。在 ERE 中,你可以使用花括号 {} 指定字符出现的确切次数。例如,要查找包含两个连续小写 'o' 的任何行,你可以使用模式 o{2}

执行以下命令。我们将模式用单引号括起来,以防止 shell 错误地解释特殊字符。

grep -E 'o{2}' /etc/passwd

输出将显示包含 "oo" 的多行:

root:x:0:0:root:/root:/bin/bash
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin

此命令有效,因为模式 o{2} 特别匹配两个连续的 'o' 字符,这些字符在 "root"、"spool" 等条目中找到。

接下来,让我们看看交替。这个强大的 ERE 功能允许你使用管道符 | 来搜索多个可能模式中的一个,它充当“或”运算符。

例如,如果你想查找用户 rootRoot 的用户记录(以防你不确定大小写),你可以使用以下命令:

grep -E 'root|Root' /etc/passwd

此命令搜索包含字符串 root 或字符串 Root 的任何行。输出显示:

root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

root 用户行和 operator 行都匹配,因为它们都包含小写 "root" 字符串。

使用 grep -E 启用的扩展正则表达式,为构建复杂搜索模式提供了更具表现力和更强大的语法,使 grep 成为文本处理中不可或缺的工具。

总结

在此实验中,你学习了如何使用 grep 命令在 Linux 中执行基本的文本搜索。你首先在一个文件中执行了针对特定字符串的基本搜索,然后将其扩展到跨多个文件进行搜索,并观察了 grep 如何在匹配行前加上相应的文件名。你还学会了使用 -n 选项来显示每次匹配的行号,这对于在文件中定位模式很有用。

此外,你还通过使用锚点来查找行开头 (^) 或结尾 ($) 的文本,探索了更高级的模式匹配功能。本次实验还涵盖了基本正则表达式和扩展正则表达式的使用,使你能够构建更复杂、更强大的搜索模式来在文件中查找特定信息。