16 个 grep 命令示例,可在现实世界中为您提供帮助

已发表: 2021-02-23

grep 最初是为基于 Unix 的系统开发的,是 Linux 机器中使用最广泛的命令行实用程序之一。

它的名字来源于ed工具中另一个类似的命令,即g/ re /p,代表g lobally search for a regular expression and p rint matching lines。 grep 基本上从标准输入或文件中搜索给定的模式或正则表达式,并打印符合给定条件的行。 它通常用于过滤掉不必要的细节,同时从大日志文件中仅打印所需的信息。

正则表达式的强大功能与 grep 中支持的选项相结合,使这成为可能。

在这里,我们将介绍一些系统管理员或开发人员在不同场景下常用的 grep 命令。

那么让我们开始吧……

grep 命令语法

如果在没有管道的情况下使用,grep 命令需要一个模式和可选参数以及一个文件列表。

 $ grep [options] pattern [files]

一个简单的例子是:

 $ 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 This is a sample text file. It contains functionality. You can always use grep with any kind of data but it works best with text data. It supports numbers like 1, 2, 3 etc. as well as This is a sample text file. It's repeated two times. $

全词搜索

我们并不总是想要部分匹配,而是希望 grep 只匹配一个完整的单词。 您可以使用-w标志来做到这一点。

 $ grep -w [pattern] [file]

输出:

 $ grep -w is text_file.txt This is a sample text file. It contains This is a sample text file. It's repeated two times. $

检查匹配计数

有时我们需要的不是实际匹配的行,而是 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 This is a sample text file. It contains This is a sample text file. It's repeated two times. $ grep -v This text_file.txt several lines to be used as part of testing grep functionality. You can always use grep with any kind of data but it works best with text data. It supports numbers like 1, 2, 3 etc. as well as alphabets and special characters like - + * # etc. $

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

打印行号

grep 允许您打印行号以及打印的行,这使得您很容易知道该行在文件中的位置。 如图所示使用-n选项获取输出中的行号。

 $ grep -n [pattern] [file]

输出:

 $ grep -n This text_file.txt 1:This is a sample text file. It contains 7:This is a sample text file. It's repeated two times. $

限制 grep 输出

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

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

请注意-m标志的使用如何影响 grep 在以下示例中针对同一组条件的输出:

 $ grep It text_file.txt This is a sample text file. It contains It supports numbers like 1, 2, 3 etc. as well as This is a sample text file. It's repeated two times. $ grep -m2 It text_file.txt This is a sample text file. It contains It supports numbers like 1, 2, 3 etc. as well as $

显示附加行

通常我们不仅需要具有匹配模式的行,还需要在其上方或下方的一些行以获得更好的上下文。

通过使用带有num值的-A-B-C标志,可以使用 grep 在具有模式的行上方或下方(或两者)打印一行。 这里的num表示要打印的额外行数,正好在匹配行的上方或下方。 这适用于 grep 在指定文件或文件列表中找到的所有匹配项。

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

或者

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

或者

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

下面的输出显示了正常的 grep 输出以及带有标志-A-B-C的输出。 请注意 grep 如何解释标志及其值以及相应输出的变化。 使用-A1标志,grep 打印紧跟在匹配行之后的 1 行。

同样,使用-B1标志,它会在匹配行之前打印 1 行。 使用-C1标志,它打印匹配行前后的 1 行。

 $ grep numbers text_file.txt It supports numbers like 1, 2, 3 etc. as well as $ grep -A1 numbers text_file.txt It supports numbers like 1, 2, 3 etc. as well as alphabets and special characters like - + * # etc. $ grep -B1 numbers text_file.txt kind of data but it works best with text data. It supports numbers like 1, 2, 3 etc. as well as $ grep -C1 numbers text_file.txt kind of data but it works best with text data. It supports numbers like 1, 2, 3 etc. as well as alphabets and special characters like - + * # etc. $

列出文件名

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

 $ grep -l [pattern] [file]

这是一个示例运行:

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

打印精确的线条

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

 $ grep -x [pattern] [file]

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

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

匹配起始字符串

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

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

例子:

 $ grep It text_file.txt This is a sample text file. It contains It supports numbers like 1, 2, 3 etc. as well as This is a sample text file. It's repeated two times. $ grep ^It text_file.txt It supports numbers like 1, 2, 3 etc. as well as $

观察使用^字符如何改变输出。 ^表示字符串的开头,grep 将^It匹配为以单词It开头的任何行。 当模式包含空格等时,用引号括起来会有所帮助。

匹配结束字符串

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

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

例子:

 $ grep "\." text_file.txt This is a sample text file. It contains functionality. You can always use grep with any kind of data but it works best with text data. It supports numbers like 1, 2, 3 etc. as well as alphabets and special characters like - + * # etc. This is a sample text file. It's repeated two times. $ grep "\.$" text_file.txt kind of data but it works best with text data. alphabets and special characters like - + * # etc. This is a sample text file. It's repeated two times. $

我们试图匹配一个. 行尾的字符。 由于点(.)是一个特殊含义的字符,我们需要用\字符对其进行转义。 再次注意当我们只匹配时输出是如何变化的. 字符,当我们使用$指示 grep 仅匹配以. (不是那些可能在两者之间的任何地方包含它的)。

使用花样文件

在某些情况下,您可能有一些经常使用的复杂模式列表。 您可以在文件中指定模式列表并使用-f标志,而不是每次都写下来。 该文件每行应包含一个模式。

 $ grep -f [pattern_file] [file_to_match]

在我们的示例中,我们创建了具有以下内容的模式文件名pattern.txt

 $ cat pattern.txt This It $

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

 $ grep -f pattern.txt text_file.txt This is a sample text file. It contains It supports numbers like 1, 2, 3 etc. as well as This is a sample text file. It's repeated two times. $

指定多个模式

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

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

例子:

 $ grep -e is -e It -e to text_file.txt This is a sample text file. It contains several lines to be used as part of testing grep It supports numbers like 1, 2, 3 etc. as well as This is a sample text file. It's repeated two times. $

指定扩展正则表达式

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

当您想按原样处理元字符并且不想像 grep 那样将它们替换为字符串时,使用 ERE 有一个优势。 这在转义它们方面为您提供了更大的灵活性,就像我们在 grep 的情况下所要求的那样。 也就是说,将-E与 grep 一起使用等同于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 grep

接下来,学习 SFTP 命令示例。