如何使用 grep 排除模式、文件和目录

已发表: 2022-06-29
显示 bash 提示符的 Linux 笔记本电脑
fatmawati achmad zaenuri/Shutterstock.com

自 1974 年以来,Linux grep命令一直在帮助人们在文件中查找字符串。 但有时grep太彻底了。 这里有几种方法可以告诉grep忽略不同的事情。

grep 命令

grep命令搜索文本文件以查找与您在命令行中提供的搜索模式相匹配的字符串。 grep的强大之处在于它使用正则表达式。 这些可以让您描述您要查找的内容,而不必明确定义它。

grep的诞生早于 Linux。 它是在 1970 年代早期在 Unix 上开发的。 它的名字来源于ed行编辑器中的 g/re/p 键序列(顺便说一下,发音为“ee-dee”)。 这代表全局常规快速搜索、打印匹配行。

grep是出了名的——也许是臭名昭著的——彻底而专一。 有时它会搜索您不希望它浪费时间的文件或目录,因为结果可能会让您无法只见树木不见森林。

如何在 Linux 上使用 grep 命令
相关如何在 Linux 上使用 grep 命令

当然,有一些方法可以控制 grep。您可以告诉它忽略模式、文件和目录,以便 grep 更快地完成搜索,并且您不会被无意义的误报所淹没。

排除模式

要使用grep进行搜索,您可以通过管道从其他进程(例如cat )向其输入输入,或者您可以提供文件名作为最后一个命令行参数。

我们正在使用一个短文件,其中包含 Lewis Carroll 的诗歌Jabberwocky的文本。 在这两个示例中,我们正在搜索与搜索词“Jabberwock”匹配的行。

 猫jabberwocky.txt | grep "Jabberwock"
 grep "Jabberwock" jabberwocky.text 

使用 grep 搜索同一文本文件的两种不同方法

为我们列出了包含与搜索线索匹配的行,每行中的匹配元素以红色突出显示。 这是简单的搜索。 但是,如果我们想排除包含“Jabberwock”这个词的行并打印其余的行怎么办?

我们可以使用-v (反转匹配)选项来实现这一点。 这列出了与搜索词不匹配的行。

 grep -v "Jabberwock" jabberwocky.text 

将 -v 反向搜索选项与 grep 一起使用

不包含“Jabberwock”的行会在终端窗口中列出。

所有不包含单词 jabberwock 的行

我们可以根据需要排除尽可能多的术语。 让我们过滤掉任何包含“Jabberwock”的行和任何包含“and”的行。 为此,我们将使用-e (表达式)选项。 我们需要将它用于我们正在使用的每个搜索模式。

 grep -v -e "Jabberwock" -e "and" jabberwocky.txt 

在 grep 中使用多个搜索子句

输出中的行数相应减少。

文本中与任一搜索词都不匹配的行

如果我们使用-E (扩展正则表达式)选项,我们可以将搜索模式与“ | “,在这种情况下并不表示管道,它是逻辑OR运算符。

 grep -Ev "Jabberwock|and" jabberwocky.txt 

在 grep 中使用逻辑 OR 运算符

我们得到的输出与之前的冗长命令完全相同。

文本中与任一搜索词都不匹配的行

如果您想使用正则表达式模式而不是显式搜索线索,则命令的格式是相同的。 此命令将排除以“ACHT”集中任何字母开头的所有行。

 grep -Ev "^ACHT" jabberwocky.txt 

排除以特定字母开头的文件

要查看包含一个模式但也不包含另一个模式的行,我们可以将grepgrep 。 我们将搜索所有包含单词“Jabberwock”的行,然后过滤掉所有包含单词“ slain ”的行。

 grep "Jabberwock" jabberwocky.txt | grep -v "被杀" 

将 grep 连接到 grep 以过滤两次

排除文件

我们可以让grep在文件集合中查找字符串或模式。 您可以在命令行上列出每个文件,但是对于许多文件,这种方法无法扩展。

 grep "vorpal" verse-1.txt verse-2.txt verse-3.txt verse-4.txt verse-5.txt verse-6.txt 

搜索命名文件列表

请注意,包含匹配行的文件的名称显示在每行输出的开头。

为了减少打字,我们可以使用通配符。 但这可能违反直觉。 这似乎有效。

 grep "vorpal" *.txt 

使用通配符搜索文件集合

但是,在这个目录下还有其他的TXT文件,与诗歌无关。 如果我们用相同的命令结构搜索“剑”这个词,我们会得到很多误报。

 grep "剑" *.txt 

通过TXT文件集合搜索“剑”

我们想要的结果被来自其他具有 TXT 扩展名的文件的大量错误结果所掩盖。

大量误报结果集

“vorpal”这个词不匹配任何东西,但是“sword”包含在“password”这个词中,因此在一些伪日志文件中多次找到它。

我们需要排除这些文件。 为此,我们将使用--exclude选项。 要排除名为“vol-log-1.txt”的单个文件,我们将使用以下命令:

 grep --exclude=vol-log-1.txt "剑" *.txt

在这种情况下,我们要排除多个名称以“vol”开头的日志文件。 我们需要的语法是:

 grep --exclude=vol*.txt "剑" *.txt 

使用通配符排除文件

当我们使用-R (dereference-recursive) 选项时, grep将为我们搜索整个目录树。 默认情况下,它将搜索这些位置的所有文件。 我们可能希望排除多种类型的文件。

在这台测试机器上的当前目录下,有嵌套的目录,其中包含日志文件、CSV 文件和 MD 文件。 这些是我们要排除的所有类型的文本文件。 我们可以为每种文件类型使用--exclude选项,但是我们可以通过对文件类型进行分组来更有效地实现我们想要的。

此命令排除所有具有 CSV 或 MD 扩展名的文件,以及所有名称以“vol”或“log”开头的 TXT 文件。

 grep -R --exclude=*.{csv,md} --exclude={vol*,log*}.txt "sword" /home/dave/data/ 

使用多个 --exclude 子句和文件名分组

排除目录

如果我们要忽略的文件包含在目录中,并且这些目录中没有我们想要搜索的文件,我们可以排除这些整个目录。

这个概念与排除文件的概念非常相似,只是我们使用--exclude-dir选项并命名要忽略的目录。

 grep -R --exclude-dir=backup "vorpal" /home/dave/data 

从搜索中排除目录

我们已经排除了“backup”目录,但我们仍在搜索另一个名为“backup2”的目录。

我们可以在一个命令中多次使用--exclude-dir选项也就不足为奇了。 请注意,排除目录的路径应相对于搜索开始的目录给出。不要使用文件系统根目录的绝对路径。

 grep -R --exclude-dir=backup --exclude-dir=backup2 "vorpal" /home/dave/data 

从搜索中排除两个目录

我们也可以使用分组。 我们可以通过以下方式更简洁地实现相同的目标:

 grep -R --exclude-dir={backup,backup2} "vorpal" /home/dave/data 

使用分组排除目录

您可以在同一命令中组合文件和目录排除项。 如果要从目录中排除所有文件并从搜索的目录排除某些文件类型,请使用以下语法:

 grep -R --exclude=*.{csv,md} --exclude-dir=backup/archive "frumious" /home/dave/data 

在同一命令中排除文件类型和目录

有时这是你遗漏的

有时使用grep感觉就像是在大海捞针。 移除干草堆有很大的不同。

相关:如何在 Linux 上使用正则表达式(regexes)