使用 Linux Shell 处理文本 - 第 2 部分 grep - 轻松搜索大海捞针

2025-06-07

使用 Linux Shell 处理文本 - 第 2 部分

grep- 轻松搜索干草堆

grep- 轻松搜索干草堆

当您需要从非常大的来源中搜索一段文本时,grep命令就是答案。grep接受字符串、正则表达式,并且可以生成各种格式的输出。

在文件中搜索一段文本的最基本语法是:

grep "pattern" file_name

如果我们需要在多个文件中搜索一个模式,我们可以执行以下操作:

grep "pattern" file1 file2 file3 ...

grep也可以与标准输入一起使用。

echo "linux is awesome" | grep linux

如果没有指定文件或目录,grep则读取STDIN输入。

# 高亮匹配的文本

grep 的一个主要功能是它能够在输出中高亮显示匹配的字符串。它有三种颜色选项:autoalwaysnever。要使用颜色选项,我们可以传递一个额外的--color标志来指示使用哪个选项。

grep "pattern" file_name --color=always

我们已经猜到了,使用--color=always选项时,它会始终为输出匹配的字符串着色。使用--color=autogrep仅当输出未通过管道传输到命令或重定向到任何文件时,才会在输出中显示颜色。最后一个选项--color=never将关闭着色。

如果您想为每个操作打开颜色grep,但又懒得--color=always为每个命令打字(我就是这样的),您可以将其添加GREP_OPTIONS到您的环境中。

export GREP_OPTIONS='--color=always'

这将为所有命令打开颜色grep

# 限制输出内容

通常情况下,grep只输出包含匹配模式的行。但在某些情况下,我们可能希望查看整个文件的内容,并高亮显示匹配的模式。为此,我们可以执行以下操作:

grep --color 'pattern\|' file_name

这将输出所有包含该模式的行以及有结尾的行,即文件的完整内容,其中仅匹配的部分被着色。当然,我们可以传递多个要匹配的模式。

grep --color 'pattern_one\|pattern_two\|' file_name

注意\前面的|。这是因为grep它只解释部分特殊字符。不过,我们也可以编写不带 的命令\

grep -E --color 'pattern_one|pattern_two|' file_name

-E选项指示grep使用完整的正则表达式。但是,还有一种更好的方法来编写包含正则表达式的模式。我们可以使用egrep,它是 的扩展版本,grep支持开箱即用的扩展正则表达式。因此,我们可以像这样重写上述命令。

egrep --color 'pattern_one|pattern_two|' file_name

但是如果我们既不需要包含匹配文本的完整行,也不需要完整的内容,而只需要匹配的内容呢?

例如,如果我们正在搜索文件中的所有电子邮件地址,我们不需要包含电子邮件的行,而只需要文件中出现的所有电子邮件。

好吧,我们可以使用-o代表仅匹配的选项,将输出限制为仅匹配的文本。

egrep -o "\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}\b" file_name

很整洁,不是吗? 

如果我们需要查看除出现给定模式的线条之外的所有线条,该怎么办?

grep -v "pattern" file_name

-v选项反转结果,因此上述命令将输出除包含匹配模式的行之外的所有内容。

# 统计出现次数

如果我们需要统计某个模式在文件中出现的次数,可以使用该-c标志。从上面的电子邮件模式示例来看,如果我们需要查看文件中有多少个电子邮件地址,可以执行以下操作。

egrep -c "\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}\b" file_name

但是等一下,还有一个问题。

仅计算-c包含该模式的行数,而不是实际匹配的行数。因此,如果一行中有多个匹配项,则只计算一次!

我们可以通过一些小调整来克服这个问题。

-o还记得我们上面是如何只打印带有标志的匹配部分吗?如果wc -l用它进行管道传输,

egrep -o "\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}\b" file_name | wc -l

它将告诉我们文件中特定模式出现的确切次数。

# 提取附加信息

如果我们想打印搜索到的模式出现的行号,我们可以使用该-n标志。

grep -n --color "pattern" file_name

如果我们在多个文件中搜索,该-n标志还将打印文件的名称。

如果我们想查看模式开始的偏移量,我们可以使用该-b标志。

echo "linux is the answer" | grep -b -o "the"

9:the由于搜索的单词“the”从该行的第 9 个位置开始,因此会打印此行。请注意,该-b标志始终与该标志一起使用-o

# 在目录内搜索

要查看哪些文件包含特定模式,我们可以使用该-l标志。

 

grep -l "pattern" file1 file2 file3 ...

这将仅输出包含指定模式的文件名。如果我们想查看不包含指定模式的文件名,可以使用-Lflag(注意 flag 区分大小写)。这基本上会反转使用-lflag 得到的结果。

到目前为止,我们只了解了如何在命令中指定的单个文件或一组文件中进行搜索。但是,我们也可以递归地搜索完整目录及其子目录中的所有文件。

grep -r "pattern" .

此处.指定当前目录。该-r标志表示应在所有子目录中递归搜索。此搜索区分大小写。

如果我们想搜索该模式的所有出现,我们可以附加-i标志。

grep -ir "pattern" .

这将输出所有匹配的模式,无论大小写如何。

# 模式文件

如果我们要搜索的模式、字符串等太多,用管道将它们连接起来|会非常繁琐。在这种情况下,我们可以使用一个模式文件,其中包含我们要搜索的所有字符串/模式,每个字符串/模式都占一行。然后,我们就可以在命令中使用该文件了grep

grep -ir . -f pattern_file

这将打印模式文件中所有匹配的字符串。

ヽ(´▽`)/

(您可以在这里找到本系列的第 1 部分

文章来源:https://dev.to/shamil/processing-text-with-linux-shell---part-2--ogo
PREV
7 天 CSS 图形和动画
NEXT
使用 Linux Shell 处理文本 - 第 1 部分 sed 的世界