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。