Linux中的Grep命令(在文件中查找文本)

grep command代表“全局正则表达式打印”,它是Linux中功能最强大且最常用的命令之一。

grep 在一个或多个输入文件中搜索与给定模式匹配的行,并将每条匹配行写入标准输出。 如果未指定文件, grep 从标准输入读取,通常是另一个命令的输出。

在本文中,我们将向您展示如何使用 grep 通过实际示例和最常见的GNU的详细说明进行命令 grep 选项。

grep 命令语法

的语法 grep 命令如下:

grep [OPTIONS] PATTERN [FILE...]

方括号中的项目是可选的。

  • OPTIONS -零个或多个选项。 Grep包含许多控制其行为的选项。
  • PATTERN -搜索模式。
  • FILE -零个或多个输入文件名。

为了能够搜索文件,运行命令的用户必须对该文件具有读取权限。

在文件中搜索字符串

最基本的用法 grep 命令是在文件中搜索字符串(文本)。

例如,显示包含字符串的所有行 bash 来自 /etc/passwd 文件,您将运行以下命令:

grep bash /etc/passwd

输出应如下所示:

root:x:0:0:root:/root:/bin/bash
linuxize:x:1000:1000:linuxize:/home/linuxize:/bin/bash

如果字符串包含空格,则需要将其用单引号或双引号引起来:

grep "Gnome Display Manager" /etc/passwd

反转匹配(排除)#

要显示与模式不匹配的行,请使用 -v ( 要么 --invert-match) 选项。

例如,要打印不包含字符串的行 nologin 您将使用:

grep -v nologin /etc/passwd
root:x:0:0:root:/root:/bin/bash
colord:x:124:124::/var/lib/colord:/bin/false
git:x:994:994:git daemon user:/:/usr/bin/git-shell
linuxize:x:1000:1000:linuxize:/home/linuxize:/bin/bash

使用Grep过滤命令的输出

可以使用以下命令过滤命令的输出 grep 通过配管,只有匹配给定图案的线将被打印在端子上。

例如,以用户身份找出系统上正在运行哪些进程 www-data 您可以使用以下内容 ps 命令:

ps -ef | grep www-data
www-data 18247 12675  4 16:00 ?        00:00:00 php-fpm: pool www
root     18272 17714  0 16:00 pts/0    00:00:00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn www-data
www-data 31147 12770  0 Oct22 ?        00:05:51 nginx: worker process
www-data 31148 12770  0 Oct22 ?        00:00:00 nginx: cache manager process

您也可以在命令中链接多个管道。 如您在上面的输出中看到的,还有一行包含 grep 处理。 如果您不希望显示该行,则将输出传递到另一行 grep 实例如下所示。

ps -ef | grep www-data | grep -v grep
www-data 18247 12675  4 16:00 ?        00:00:00 php-fpm: pool www
www-data 31147 12770  0 Oct22 ?        00:05:51 nginx: worker process
www-data 31148 12770  0 Oct22 ?        00:00:00 nginx: cache manager process

要递归搜索模式,请调用 grep-r 选项(或 --recursive)。 使用此选项时 grep 将搜索指定目录中的所有文件,并跳过递归遇到的符号链接。

跟随所有符号链接,而不是 -r, 使用 -R 选项(或 --dereference-recursive)。

这是显示如何搜索字符串的示例 linuxize.com 在里面的所有文件中 /etc 目录:

grep -r linuxize.com /etc

输出将包含以文件的完整路径为前缀的匹配行:

/etc/hosts:127.0.0.1 node2.linuxize.com
/etc/nginx/sites-available/linuxize.com:    server_name linuxize.com   www.linuxize.com;

如果您使用 -R 选项, grep 将遵循所有符号链接:

grep -R linuxize.com /etc

注意下面输出的最后一行。 该行在以下情况下不打印 grep 被调用 -r因为Nginx内的文件 sites-enabled 目录是指向内部的配置文件的符号链接 sites-available 目录。

/etc/hosts:127.0.0.1 node2.linuxize.com
/etc/nginx/sites-available/linuxize.com:    server_name linuxize.com   www.linuxize.com;
/etc/nginx/sites-enabled/linuxize.com:    server_name linuxize.com   www.linuxize.com;

仅显示文件名

禁止默认 grep 输出并仅打印包含匹配模式的文件的名称,请使用 -l ( 要么 --files-with-matches) 选项。

以下命令搜索所有以结尾的文件 .conf 在当前工作目录中,仅显示包含字符串的文件的名称 linuxize.com

grep -l linuxize.com *.conf

输出将如下所示:

tmux.conf
haproxy.conf

-l 选项通常与递归选项结合使用 -R

grep -Rl linuxize.com /tmp

默认, grep 区分大小写。 这意味着将大写和小写字符视为不同的字符。

要在搜索时忽略大小写,请调用 grep-i 选项(或 --ignore-case)。

例如,当搜索 Zebra 没有任何选项,以下命令将不显示任何输出,即有匹配的行:

grep Zebra /usr/share/words

但是,如果您使用 -i 选项,它将同时匹配大写和小写字母:

grep -i Zebra /usr/share/words

指定“ Zebra”将匹配该字符串的“ zebra”,“ ZEbrA”或任何其他大小写字母组合。

zebra
zebra's
zebras

搜索全词

搜索字符串时, grep 将显示该字符串嵌入较大字符串中的所有行。

例如,如果搜索“ gnu”,则将以较大的单词(例如“ cygnus”或“ magnum”)嵌入“ gnu”的所有行都将匹配:

grep gnu /usr/share/words
cygnus
gnu
interregnum
lgnu9d
lignum
magnum
magnuson
sphagnum
wingnut

要仅返回指定字符串是整个单词(用非单词字符括起来)的那些行,请使用 -w ( 要么 --word-regexp) 选项。

文字字符包括字母数字字符(a-zA-Z0-9)和下划线(_)。 所有其他字符均视为非单词字符。

如果您运行与上述相同的命令,包括 -w 选项, grep 该命令将仅返回其中的行 gnu 作为一个单独的词包括在内。

grep -w gnu /usr/share/words
gnu

显示行号

-n ( 要么 --line-number)选项告诉 grep 显示包含与模式匹配的字符串的行的行号。 使用此选项时, grep 将匹配项打印到以行号为前缀的标准输出。

例如显示 /etc/services 包含字符串的文件 bash 以匹配的行号为前缀,您可以使用以下命令:

grep -n 10000 /etc/services

下面的输出向我们显示了在10423和10424行上找到的匹配项。

10423:ndmp            10000/tcp
10424:ndmp            10000/udp

计算比赛次数

要将匹配的行数打印到标准输出,请使用 -c ( 要么 --count) 选项。

在下面的示例中,我们计算的是拥有 /usr/bin/zsh 作为外壳。

regular expressiongrep -c '/usr/bin/zsh' /etc/passwd
4

静音模式 #

-q (要么 --quiet)告诉 grep 在安静模式下运行,不要在标准输出上显示任何内容。 如果找到匹配项,则命令以状态退出 0。 使用时这很有用 grep 在要检查文件是否包含字符串并根据结果执行某些操作的shell脚本中。

这是使用示例 grep 在安静模式下作为测试命令 if 声明:

if grep -q PATTERN filename
then
    echo pattern found
else
    echo pattern not found
fi

基本正则表达式

GNU Grep具有三个正则表达式功能集,即Basic,Extended和Perl兼容。

默认, grep 将模式解释为基本正则表达式,其中除元字符以外的所有字符实际上都是与自己匹配的正则表达式。

以下是最常用的元字符列表:

  • 使用 ^ (脱字符)符号以匹配行首的表达式。 在下面的示例中,字符串 kangaroo 仅在行的开头出现时才匹配。

    grep "^kangaroo" file.txt
  • 使用 $ (美元)符号以匹配行尾的表达式。 在下面的示例中,字符串 kangaroo 仅当它出现在行的末尾时才匹配。

    grep "kangaroo$" file.txt
  • 使用 . (句点)符号以匹配任何单个字符。 例如,匹配任何以 kan 然后有两个字符并以字符串结尾 roo,您可以使用以下模式:

    grep "kan..roo" file.txt
  • 使用 [ ] (括号)以匹配括号中包含的任何单个字符。 例如,找到包含以下内容的行 accept 要么 ”accent,您可以使用以下模式:

    grep "acce[np]t" file.txt
  • 使用 [^ ] 匹配括号中未包含的任何单个字符。 以下模式将匹配包含以下内容的字符串的任意组合: co(any_letter_except_l)a, 如 cocacobalt 依此类推,但与包含以下内容的行不匹配 cola

    grep "co[^l]a" file.txt

要转义下一个字符的特殊含义,请使用 (反斜杠)符号。

扩展正则表达式

要将模式解释为扩展的正则表达式,请使用 -E ( 要么 --extended-regexp) 选项。 扩展的正则表达式包括所有基本的元字符,以及用于创建更复杂和更强大的搜索模式的其他元字符。 以下是一些示例:

  • 匹配并提取给定文件中的所有电子邮件地址:

    grep -E -o "b[A-Za-z0-9._%+-][email protected][A-Za-z0-9.-]+.[A-Za-z]{2,6}b" file.txt
  • 匹配并提取给定文件中的所有有效IP地址:

    grep -E -o '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)' file.txt

-o 选项仅用于打印匹配的字符串。

搜索多个字符串(模式)#

可以使用OR运算符合并两个或多个搜索模式 |

默认, grep 将模式解释为基本正则表达式,其中的元字符如 | 失去其特殊含义,必须使用反斜杠版本。

在下面的示例中,我们正在搜索所有出现的单词 fatalerrorcritical 在Nginx日志错误文件中:

grep 'fatal|error|critical' /var/log/nginx/error.log

如果您使用扩展的正则表达式选项 -E,然后是运算符 | 不应逃脱,如下所示:

grep -E 'fatal|error|critical' /var/log/nginx/error.log

要在匹配行之前打印特定数量的行,请使用 -B ( 要么 --before-context) 选项。

例如,要在匹配的行之前显示五行前导上下文,可以使用以下命令:

grep -B 5 root /etc/passwd

要在匹配的行之后打印特定数量的行,请使用 -A ( 要么 --after-context) 选项。

例如,要在匹配的行之后显示五行尾随上下文,可以使用以下命令:

grep -A 5 root /etc/passwd

结论#

grep 命令允许您在文件内部搜索模式。 如果找到匹配项,则grep打印包含指定模式的行。

在“ Grep用户手册”页面上,还有更多有关Grep的知识。

如果您有任何疑问或反馈,请随时发表评论。

grep终端

Sidebar