使用 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 的一个主要功能是它能够在输出中高亮显示匹配的字符串。它有三种颜色选项:auto
、always
和never
。要使用颜色选项,我们可以传递一个额外的--color
标志来指示使用哪个选项。
grep "pattern" file_name --color=always
我们已经猜到了,使用--color=always
选项时,它会始终为输出匹配的字符串着色。使用--color=auto
,grep
仅当输出未通过管道传输到命令或重定向到任何文件时,才会在输出中显示颜色。最后一个选项--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 ...
这将仅输出包含指定模式的文件名。如果我们想查看不包含指定模式的文件名,可以使用-L
flag(注意 flag 区分大小写)。这基本上会反转使用-l
flag 得到的结果。
到目前为止,我们只了解了如何在命令中指定的单个文件或一组文件中进行搜索。但是,我们也可以递归地搜索完整目录及其子目录中的所有文件。
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