16个grep命令示例,帮助你在现实世界中使用

grep,最初是为Unix系统开发的,是Linux系统中最常用的命令行实用程序之一。

它的名称来自于另一个类似的ed工具中的命令,即g/re/p,它代表全局搜索一个正则表达式并打印匹配行。grep基本上是从标准输入或文件中搜索给定的模式或正则表达式,并打印符合给定条件的行。它经常用于从大型日志文件中打印所需信息时过滤掉不必要的细节。

regular expression的功能与grep中支持的选项结合在一起,使得这一点成为可能。

这里我们将介绍一些在不同场景中常用的grep命令,供sysadmin或开发人员使用。

那么,让我们开始吧…👨‍💻

grep命令语法

grep命令需要一个模式和可选的参数,以及一个文件列表(如果不使用管道)。

$ grep [选项] 模式 [文件]

一个简单的例子是:

$ grep my file.txt
my_file
$

搜索多个文件

grep使您可以不仅在一个文件中搜索给定的模式,而且在多个文件中搜索。以下是如何使用*通配符在多个文件中查找模式。

$ sudo grep -i err /var/log/messages*

输出:

$ sudo grep err /var/log/messages*
/var/log/messages:Dec 28 10:36:52 centos7vm kernel: ACPI: Using IOAPIC for interrupt routing
/var/log/messages:Dec 28 10:36:52 centos7vm kernel: ACPI: PCI Interrupt Link [LNKA] (IRQs 5 9 10 *11)
/var/log/messages:Dec 28 10:36:52 centos7vm kernel: ACPI: PCI Interrupt Link [LNKB] (IRQs 5 9 *10 11)
/var/log/messages:Dec 28 10:36:52 centos7vm kernel: ACPI: PCI Interrupt Link [LNKC] (IRQs 5 *9 10 11)
/var/log/messages:Dec 28 10:36:52 centos7vm kernel: ACPI: PCI Interrupt Link [LNKD] (IRQs 5 9 10 *11)
/var/log/messages-20201225:Dec 23 23:01:00 centos7vm kernel: ACPI: Using IOAPIC for interrupt routing
/var/log/messages-20201225:Dec 23 23:01:00 centos7vm kernel: ACPI: PCI Interrupt Link [LNKA] (IRQs 5 9 10 *11)
/var/log/messages-20201225:Dec 23 23:01:00 centos7vm kernel: ACPI: PCI Interrupt Link [LNKB] (IRQs 5 9 *10 11)
/var/log/messages-20201225:Dec 23 23:01:00 centos7vm kernel: ACPI: PCI Interrupt Link [LNKC] (IRQs 5 *9 10 11)
/var/log/messages-20201225:Dec 23 23:01:00 centos7vm kernel: ACPI: PCI Interrupt Link [LNKD] (IRQs 5 9 10 *11)
/var/log/messages-20201225:Dec 23 23:01:00 centos7vm kernel: BERT: Boot Error Record Table support is disabled. Enable it by using bert_enable as kernel parameter.
/var/log/messages-20201227:Dec 27 19:11:18 centos7vm kernel: ACPI: PCI Interrupt Link [LNKA] (IRQs 5 9 10 *11)
/var/log/messages-20201227:Dec 27 19:11:18 centos7vm kernel: ACPI: PCI Interrupt Link [LNKB] (IRQs 5 9 *10 11)
/var/log/messages-20201227:Dec 27 19:11:18 centos7vm kernel: ACPI: PCI Interrupt Link [LNKC] (IRQs 5 *9 10 11)
/var/log/messages-20201227:Dec 27 19:11:18 centos7vm kernel: ACPI: PCI Interrupt Link [LNKD] (IRQs 5 9 10 *11)
/var/log/messages-20201227:Dec 27 19:11:18 centos7vm kernel: BERT: Boot Error Record Table support is disabled. Enable it by using bert_enable as kernel parameter.
/var/log/messages-20201227:Dec 27 19:11:21 centos7vm kernel: [drm:vmw_host_log [vmwgfx]] *ERROR* Failed to send host log message.
/var/log/messages-20201227:Dec 27 19:11:21 centos7vm kernel: [drm:vmw_host_log [vmwgfx]] *ERROR* Failed to send host log message.
$

从上面的输出中可以看出,在打印匹配行之前,首先打印了文件名,以指示grep在哪里找到给定的模式。

大小写不敏感搜索

grep可以在搜索模式时忽略模式的大小写。使用-i标志告诉grep忽略大小写。

$ grep -i [pattern] [file]

输出:

$ grep -i it text_file.txt
这是一个示例文本文件。它包含
功能。您可以始终使用grep与任何
各种数据,但它最适用于文本数据。
它还支持像1、2、3等数字
这是一个示例文本文件。它重复了两次。
$

完整单词搜索

我们并不总是想要部分匹配,而是期望grep只匹配完整的单词。您可以使用-w标志来实现。

$ grep -w [pattern] [file]

输出:

$ grep -w is text_file.txt
这是一个示例文本文件。它包含
这是一个示例文本文件。它重复了两次。
$

检查匹配数量

有时我们不需要实际匹配的行,而只需要grep成功匹配的计数。我们可以使用-c选项获取此计数。

$ grep -c [pattern] [file]

输出:

$ grep -c is text_file.txt
2
$

搜索子目录

通常需要在当前工作目录以及子目录中搜索文件。grep允许您使用-r标志轻松完成此操作。

$ grep -r [pattern] *

输出:

$ grep -r Hello *
dir1/file1.txt:Hello One
dir1/file2.txt:Hello Two
dir1/file3.txt:Hello Three
$

正如您所观察到的,grep遍历当前目录中的每个子目录,并列出找到匹配项的文件和行。

反向搜索

如果您想要查找与给定模式不匹配的内容,grep允许使用-v标志完成此操作。

$ grep -v [pattern] [file]

输出:

$ grep This text_file.txt
这是一个示例文本文件。它包含
这是一个示例文本文件。它重复了两次。
$ grep -v This text_file.txt
用于测试grep的几行
功能。您可以始终使用grep与任何
各种数据,但它最适用于文本数据。
它还支持数字1、2、3等
字母和特殊字符如- + * #等。
$

您可以将带有和不带有-v标志的同一模式和文件的grep命令的输出进行比较。使用-v,不匹配模式的任何行都会被打印出来。

打印行号

grep允许您在打印的行中打印行号,这样可以轻松知道行在文件中的位置。使用-n选项如下所示以获取输出中的行号。

$ grep -n [pattern] [file]

输出:

$ grep -n This text_file.txt
1:这是一个示例文本文件。它包含
7:这是一个示例文本文件。它重复了两次。
$

限制grep输出

对于像日志文件等大文件,grep输出可能会很长,您可能只需要输出中的固定行数,而不是匹配所有内容。我们可以使用-m[num]来通过num限制打印的行数。这是如何使用它的:

$ grep -m[num] [pattern] [file]

请注意,使用-m标志会影响grep的输出,即使在下面的示例中具有相同的条件:

显示额外行

通常,我们不仅需要具有匹配模式的行,还需要一些上下文中的上下文行。

使用grep可以打印具有模式的行的上面或下面的行(或两者)-A-B-C标志与num值。这里的num表示要打印的附加行数,其刚好在匹配行的上方或下方。这适用于grep在指定的文件或文件列表中找到的所有匹配。

$ grep -A[num] [pattern] [file]

或者

$ grep -B[num] [pattern] [file]

$ grep -C[num] [pattern] [file]

下面的输出显示了正常的grep输出以及使用标志-A-B-C分别的输出。请注意grep如何解释标志及其值以及相应输出中的更改。使用-A1标志,grep打印出与匹配行紧随其后的一行。

类似地,使用-B1标志,它在匹配行之前打印1行。使用-C1标志,它打印出在匹配行之前和之后的1行。

$ grep numbers text_file.txt
它支持1, 2, 3等数字
$ grep -A1 numbers text_file.txt
它支持1, 2, 3等数字
字母和特殊字符,如- + *#等。
$ grep -B1 numbers text_file.txt
数据的种类,但它在处理文本数据时效果最好。
它支持1, 2, 3等数字
$ grep -C1 numbers text_file.txt
数据的种类,但它在处理文本数据时效果最好。
它支持1, 2, 3等数字
字母和特殊字符,如- + *#等。
$

列表文件名

要仅打印出模式匹配的文件的名称,而不是实际匹配的行,请使用-l标志。

$ grep -l [pattern] [file]

以下是一个示例运行:

$ grep -l su *.txt
file.txt
text_file.txt
$

打印确切行

有时,我们需要打印与给定模式完全匹配的行,而不是某些部分。grep允许使用-x标志来实现这一点。

$ grep -x [pattern] [file]

在下面的示例中,file.txt包含只有一个单词“ support”的行,因此grep使用-x标志与可能包含单词“ support”的行匹配,而忽略包含其他文本的行。

$ grep -x support *.txt
file.txt:support
$ 

匹配起始字符串

使用正则表达式,我们可以在行的开头找到一个字符串。下面是如何做的。

$ grep [options] "^[string]" [file]

示例:

$ grep It text_file.txt
这是一个示例文本文件。它包含
它支持数字1, 2, 3等等,以及
这是一个示例文本文件。它重复了两次。
$ grep ^It text_file.txt
它支持数字1, 2, 3等等,以及
$

观察如何使用^字符更改输出。 ^表示字符串的开头,并且grep将^It与以单词It开头的任何行匹配。将其括在引号中可以在模式中包含空格等。

匹配结束字符串

另一个常用的有用的正则表达式是匹配行尾的模式。

$ grep [options] "[string]$" [file]

示例:

$ grep "." text_file.txt
这是一个示例文本文件。它包含
功能。您可以始终使用grep与任何
所有类型的数据,但在处理文本数据时效果最佳。
它支持数字,如1,2,3等,还支持
字母和特殊字符,如- + *#等。
这是一个示例文本文件。它重复了两次。
$ grep ".$" text_file.txt
它支持所有类型的数据,但在处理文本数据时效果最佳。
字母和特殊字符,如- + *#等。
这是一个示例文本文件。它重复了两次。
$

我们尝试匹配行尾的.字符。由于点(.)是一个特殊的含义字符,我们需要使用字符进行转义。再次注意,当我们只匹配.字符和当我们使用$指示grep仅匹配以.结尾的行时,输出是如何变化的(而不是包含它的任何位置)。

使用模式文件

可能存在这样的情况,即您经常使用某些复杂的模式列表。您可以在每次写下它们之前指定一个模式列表文件并使用-f标志。文件应每行包含一个模式。

$ grep -f [pattern_file] [file_to_match]

在我们的示例中,我们创建了一个名为pattern.txt的模式文件,其内容如下:

$ cat pattern.txt
This
It
$

要使用它,请使用-f标志。

$ grep -f pattern.txt text_file.txt
这是一个示例文本文件。它包含
它支持数字,如1,2,3等,以及
这是一个示例文本文件。它重复了两次。
$

指定多个模式

grep允许使用-e标志指定多个模式。

$ grep -e [pattern1] -e [pattern2] -e [pattern3]...[file]

示例:

$ grep -e is -e It -e to text_file.txt
这是一个示例文本文件。它包含
作为grep测试的一部分要使用的几行
它支持数字,如1,2,3等,以及
这是一个示例文本文件。它重复了两次。
$

指定扩展正则表达式

grep还支持使用-E标志的扩展正则表达式或ERE。这类似于Linux中的egrep命令。

使用ERE的一个优点是,当您希望按原样处理元字符时,并且不希望像grep那样将它们替换为字符串时,可以使用它。这使您在转义它们时具有更大的灵活性,就像我们在grep的情况下所要求的那样。也就是说,使用grep的-E等效于egrep命令。

$ grep -E '[Extended RegEx]' [file]

这是ERE的一个用法示例,我们希望打印未被注释或空白的行。这对于在大型配置文件中查找某些内容非常有用。我还使用了-v标志来不打印匹配模式'^(#|$)'的行。

$ sudo grep -vE '^(#|$)' /etc/ssh/sshd_config
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
SyslogFacility AUTHPRIV
AuthorizedKeysFile      .ssh/authorized_keys
PasswordAuthentication yes
ChallengeResponseAuthentication no
GSSAPIAuthentication yes
GSSAPICleanupCredentials no
UsePAM yes
X11Forwarding yes
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
AcceptEnv XMODIFIERS
Subsystem       sftp    /usr/libexec/openssh/sftp-server
$

结论

以上示例只是冰山一角。grep支持多种选项,并且对于知道如何有效使用它的人来说,它可以是一个非常强大的工具。我们不仅可以使用上述示例,还可以以不同的方式结合它们以获得所需的内容。

请参阅其man页面以了解更多信息。

$ man grep

接下来,学习SFTP command examples

类似文章