在本教程中,您将学习如何使用非常重要的grepLinux 中的命令。我们将讨论为什么掌握这个命令很重要,以及如何在命令行的日常任务中使用它。
让我们通过一些解释和示例来深入探讨。
为什么我们使用 grep?
Grep 是 Linux 用户用来搜索文本字符串的命令行工具。您可以使用它来搜索文件中的某个单词或单词组合,也可以通过管道传输其他单词的输出Linux命令grep,因此 grep 可以只显示您需要查看的输出。
让我们看一些非常常见的例子。假设您需要检查目录的内容以查看其中是否存在某个文件。这就是你可以使用“ls”命令的目的。
但是,为了使检查目录内容的整个过程更快,您可以将 ls 命令的输出通过管道传递给 grep 命令。让我们在主目录中查找名为 Documents 的文件夹。
现在,让我们尝试再次检查目录,但这次使用 grep 专门检查 Documents 文件夹。
$ ls | grep Documents
正如您在上面的屏幕截图中看到的,使用 grep 命令可以快速将我们搜索的单词与 ls 命令产生的其余不必要的输出隔离开来,从而节省了我们的时间。
如果 Documents 文件夹不存在,grep 将不会返回任何输出。因此,如果 grep 没有返回任何内容,则意味着它找不到您要搜索的单词。
查找字符串
如果您需要搜索文本字符串,而不仅仅是单个单词,则需要将该字符串括在引号中。例如,如果我们需要搜索“我的文档”目录而不是单字“文档”目录怎么办?
$ ls | grep 'My Documents'
Grep 将接受单引号和双引号,因此请使用其中之一将文本字符串括起来。
虽然您可以使用 grep 搜索从其他命令行工具传递的输出,但您也可以使用它直接搜索文档。这是一个在文本文档中搜索字符串的示例。
$ grep 'Class 1' Students.txt
查找多个字符串
您还可以使用 grep 查找多个单词或字符串。您可以使用 -e 开关指定多个模式。让我们尝试在文本文档中搜索两个不同的字符串:
$ grep -e 'Class 1' -e Todd Students.txt
请注意,我们只需要在包含空格的字符串周围使用引号。
grep、egrep fgrep、pgrep、zgrep 之间的区别
历史上,各种 grep 开关包含在不同的二进制文件中。在现代 Linux 系统上,您会发现这些开关在基本 grep 命令中可用,但发行版也通常支持其他命令。
从 grep 的手册页中:
egrep 相当于 grep -E
该开关会将模式解释为扩展正则表达式。您可以用它做很多不同的事情,但这里有一个使用 grep 正则表达式的示例。
让我们在文本文档中搜索包含两个连续“p”字母的字符串:
$ egrep p\{2} fruits.txt
or
$ grep -E p\{2} fruits.txt
fgrep 相当于 grep -F
此开关将模式解释为固定字符串列表,并尝试匹配其中的任何一个。当您需要搜索正则表达式字符时,它非常有用。这意味着您不必像使用常规 grep 那样转义特殊字符。
pgrep 是一个命令,用于搜索系统上正在运行的进程的名称并返回其各自的进程 ID。例如,您可以使用它来查找 SSH 守护程序的进程 ID:
$ pgrep sshd
这在功能上类似于将“ps”命令的输出通过管道传递给 grep。
您可以使用此信息杀死一个正在运行的进程或解决系统上运行的服务的问题。
您可以使用 zgrep 搜索压缩文件中的模式。它允许您搜索压缩存档内的文件,而无需先解压缩该存档,基本上节省了您一两个额外的步骤。
$ zgrep apple fruits.txt.gz
zgrep 也适用于 tar 文件,但似乎只能告诉您它是否能够找到匹配项。
我们提到这一点是因为使用 gzip 压缩的文件通常是 tar 存档。
查找和 grep 之间的区别
对于那些刚刚开始使用 Linux 命令行的人来说,重要的是要记住 find 和 grep 是两个具有两个非常不同功能的命令,尽管我们使用这两个命令来“查找”用户指定的内容。
当您使用 grep 来搜索 ls 命令的输出时,使用 grep 来查找文件会很方便,正如我们在本教程的第一个示例中所示的那样。
但是,如果您需要递归搜索文件名(或者使用通配符(星号)则搜索文件名的一部分),则可以使用“find”命令。
$ find /path/to/search -name name-of-file
上面的输出表明查找命令能够成功找到我们搜索的文件。
递归搜索
您可以将 -r 开关与 grep 结合使用,以递归方式搜索目录及其子目录中的所有文件以查找指定模式。
$ grep -r pattern /directory/to/search
如果您不指定目录,grep 将只搜索您当前的工作目录。在下面的屏幕截图中,grep 找到了两个与我们的模式匹配的文件,并返回它们的文件名和它们所在的目录。
捕获空格或制表符
正如我们前面在解释如何搜索字符串时提到的,如果文本包含空格,您可以将文本括在引号内。同样的方法也适用于选项卡,但我们稍后将解释如何在 grep 命令中添加选项卡。
在引号内放入一个或多个空格即可让 grep 搜索该字符。
$ grep " " sample.txt
您可以通过几种不同的方法使用 grep 搜索选项卡,但大多数方法都是实验性的,或者在不同的发行版中可能不一致。
最简单的方法是只搜索制表符本身,您可以通过在键盘上按 ctrl+v,然后按制表符来生成该字符。
通常,在终端窗口中按 Tab 会告诉终端您要自动完成命令,但事先按 ctrl+v 组合将导致制表符按照您通常在文本编辑器中期望的方式写出。
$ grep " " sample.txt
在 Linux 中查找配置文件时,了解这个小技巧特别有用,因为制表符经常用于将命令与其值分开。
使用正则表达式
Grep 的功能通过使用正则表达式得到进一步扩展,使您的搜索更加灵活。存在几种,我们将在下面的示例中介绍一些最常见的:
[ ] 括号用于匹配任意一组字符。
$ grep "Class [123]" Students.txt
此命令将返回任何显示“Class 1”、“Class2”或“Class 3”的行。
[-] 带连字符的括号可用于指定字符范围,无论是数字还是字母。
$ grep "Class [1-3]" Students.txt
我们得到与以前相同的输出,但命令更容易键入,特别是如果我们有更大范围的数字或字母。
^ caret用于搜索仅出现在行开头的模式。
$ grep "^Class" Students.txt
[^] 带插入符号的括号用于从搜索模式中排除字符。
$ grep "Class [^1-2]" Students.txt
$ 美元符号用于搜索仅出现在行尾的模式。
$ grep "1$" Students.txt
. dot 用于匹配任意一个字符,因此它是一个通配符,但仅适用于单个字符。
$ grep "A….a" Students.txt
Grep gz 文件而不解压
正如我们之前所展示的,您可以使用 zgrep 命令搜索压缩文件,而无需先解压缩它们。
$ zgrep word-to-search /path/to/file.gz
您还可以使用 zcat 命令显示 gz 文件的内容,然后将该输出通过管道传输到 grep 以隔离包含搜索字符串的行。
$ zcat file.gz | grep word-to-search
Grep zip 文件中的电子邮件地址
我们可以使用奇特的正则表达式从 zip 文件中提取所有电子邮件地址。
$ grep -o '[[:alnum:]+\.\_\-]*@[[:alnum:]+\.\_\-]*' emails.txt
-o 标志将提取电子邮件地址only,而不是显示包含电子邮件地址的整行。这会产生更干净的输出。
与 Linux 中的大多数事情一样,有不止一种方法可以做到这一点。您还可以使用egrep 和一组不同的表达式。但上面的示例工作得很好,并且是提取电子邮件地址并忽略其他所有内容的非常简单的方法。
查询 IP 地址
Grep 查找 IP 地址可能会变得有点复杂,因为我们不能只告诉 grep 查找由点分隔的四个数字 - 好吧,我们could,但该命令也有可能返回无效的 IP 地址。
以下命令将查找并隔离only valid IPv4 地址:
$ grep -E -o "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" /var/log/auth.log
我们在 Ubuntu 服务器上使用它只是为了查看最新的 SSH 尝试是从哪里进行的。
为了避免重复信息并防止其淹没屏幕,您可能需要将 grep 命令通过管道传输到“uniq”和“more”,就像我们在上面的屏幕截图中所做的那样。
grep 或条件
您可以通过几种不同的方式在 grep 中使用 or 条件,但我们将向您展示需要最少击键次数且最容易记住的一种方式:
$ grep -E 'string1|string2' filename
或者,从技术上讲,使用 egrep 的击键次数甚至更少:
$ egrep 'string1|string2' filename
忽略大小写
默认情况下,grep 区分大小写,这意味着搜索字符串的大小写必须精确。您可以通过使用 -i 开关告诉 grep 忽略大小写来避免这种情况。
$ grep -i string filename
搜索时区分大小写
如果我们想要搜索一个字符串,其中第一个可以是大写或小写,但字符串的其余部分应该是小写怎么办?在这种情况下,使用 -i 开关忽略大小写将不起作用,因此一个简单的方法是使用括号。
$ grep [Ss]tring filename
此命令告诉 grep 除第一个字母外区分大小写。
grep 精确匹配
在上面的示例中,每当我们在文档中搜索字符串“apple”时,grep 也会返回“pineapple”作为输出的一部分。为了避免这种情况,并严格搜索“apple”,您可以使用以下命令:
$ grep "\<apple\>" fruits.txt
您还可以使用 -w 开关,它会告诉 grep 该字符串必须匹配整行。显然,这只适用于您不希望该行的其余部分有任何文本的情况。
排除模式
要查看文件的内容但从输出中排除模式,可以使用 -v 开关。
$ grep -v string-to-exclude filename
正如您在屏幕截图中看到的,当我们使用 -v 开关运行相同的命令时,我们排除的字符串不再显示。
查找并替换
通过管道传输到 sed 的 grep 命令可用于替换文件中字符串的所有实例。此命令将在与当前工作目录相关的所有文件中将“string1”替换为“string2”:
$ grep -rl 'string1' ./ | xargs sed -i 's/string1/string2/g'
带行号的 Grep
要显示包含字符串的行号,请使用 -n 开关:
$ grep -n string filename
显示之前和之后的行
如果您需要 grep 输出的更多上下文,您可以使用 -c 开关在指定的搜索字符串之前和之后显示一行:
$ grep -c 1 string filename
指定您希望显示的行数 - 在本例中我们只显示了 1 行。
对结果进行排序
将 grep 输出通过管道传输到 sort 命令,以按某种顺序对结果进行排序。默认按字母顺序排列。
$ grep string filename | sort
我希望您觉得本教程有用。继续回来。