对多个字符串使用 Grep

Niraj Menon 2022年5月11日
对多个字符串使用 Grep

作为 Bash 脚本编写者,你可能会发现自己需要解析大量文本以获取相关信息。有时该信息是无序的,这需要你找出一种模式来捕获所有相关数据。

在 Linux 中完成这项工作的最佳工具是由 Ken Thompson 在 1973 年左右编写的 grepgrep 适用于所有现代 UNIX 系统。

本教程将广泛涵盖 grep 的使用,从基本示例(例如捕获单个短语到使用正则表达式或固定字符串捕获多个模式,假设使用 Bash 命令行)。

使用 grep 捕获简单的短语

使用 grep 的最简单方法是查找文件中出现的短语。给定一个目标词和一个文件,我们可以在文件中搜索该词,如图所示。

user@linux:~$ cat file.txt
UNIX
tutorial
word
words
sword
tests
Linux

user@linux:~$ grep word file.txt
word
words
sword

正如你在上面看到的,所有包含子字符串 word 的单词都被捕获。

你还可以捕获程序的输出并 grep 短语的输出,如图所示。我们将继续使用该文件作为示例,但你可以使用任何打印到 stdout 的程序来执行此操作。

user@linux:~$ cat file.txt | grep word
word
words
sword

如果你希望 grep 仅打印完全匹配的短语(即,它们周围有空格并且不是其他单词的子字符串),你可以使用 -w/--word-regexp 标志来启用整体词匹配。

如果短语显示为单行,你可以使用相同的想法来匹配短语,使用 -x/--line-regexp

user@linux:~$ cat file.txt | grep -w word
word

带有多个字符串的 grep

要使用由换行符分隔的多个短语来捕获来自程序的文件或文本流中的相关匹配,你可以使用 -F/--fixed-strings 来指定它们。

你可以传入一个如下所示的字符串来代替少量匹配,用美元符号表示换行符。

grep -F "words$word" file.txt
# or
fgrep "words$word" file.txt

对于文件中的更大列表,你可以使用 cat 将文件打印为 grep 的参数并重用相同的语法。

user@linux:~$ cat match.txt
word
sword
user@linux:~$ fgrep "$(cat match.txt)" file.txt
word
words
sword

grep 与正则表达式

如果你熟悉 RegEx,本节将非常方便。使用 -E/--extended-regexp,你可以指定一个正则表达式模式来捕获更复杂的短语,这些短语不能用单个或多个短语来捕捉。

给定一个随机包含电子邮件地址和 URL 的文件,我们可能希望通过单独调用 grep 命令过滤掉与电子邮件或 URL 匹配的行。

用于捕获电子邮件的一个简单的、主要是幼稚的 RegEx 模式是 [^\@]+\@[^\.]+.*。要将其与 grep 一起使用,你可以执行以下操作:

user@linux:~$ cat file.txt 
user@linux.com
linux@torvalds.com
not a URL or email
https://www.google.com/
https://apple.com/
not an email or URL
user@linux:~$ egrep '[^\@]+\@[^\.]+.*' file.txt
user@linux.com
linux@torvalds.com

另一个利用 RegEx 的示例是指定多个模式以查看它们中的每一个是否都存在于文件中。为此,我们有以下模式。

请注意以下示例中使用的两种 RegEx 模式之间的比较 - 一种使用 OR 运算符,另一种是这样编写的,该行必须包含所有三个单词。

user@linux:~$ cat file.txt
apple banana grape
bus lamppost bench
apple bench grape
bus grape lamppost
yellow apple bus
user@linux:~$ grep -P 'apple|banana|grape' file.txt
apple banana grape
apple bench grape
banana grape apple
bus grape lamppost
yellow apple bus
user@linux:~$ grep -P '^(?=.*apple)(?=.*banana)(?=.*grape)' file.txt
apple banana grape
banana grape apple

请记住,grep 并不是 UNIX 系统中唯一可用的字符串匹配工具。你也可以使用 awk 来捕捉复杂的模式。你还可以使用 sed 根据匹配条件替换短语。

本教程从 grep 手册页获取信息,你可以通过在任何 UNIX 终端或此页上键入 man grep 来访问该手册页。

相关文章 - Linux Grep