grep命令的全称是全局正则表达式打印,它是Linux中功能最强大且最常用的命令之一。
grep在一个或多个输入文件中搜索与指定模式匹配的行,并将匹配行写入标准输出。如果未指定文件,grep则从标准输入读取内容。
grep命令读取的标准输入通常是另一个命令的输出。在本教程中,我们将通过实际示例向您展示如何使用grep
命令并详细说明最常用的GNU grep
选项。
grep 命令
在开始使用grep
命令之前,让我们先回顾一下grep基本语法。grep
命令的语法形式是grep [OPTIONS] PATTERN [FILE...]
。
OPTIONS
可选参数可以零个或多个选项,PATTERN
搜索模式可以是字符串,也可以是正则表达式。
FILE
零个或多个输入文件名。要能够搜索文件,运行grep
命令的用户必须对文件具有读取权限。
grep 搜索字符串
grep命令的最基本用法是在文件中搜索字符串。如果字符串包含空格,则需要将其用单引号或双引号引起来。
例如命令grep "Gnome Display Manager" /etc/passwd
在文件/etc/passwd
搜索Gnome Display Manager
。
命令grep bash /etc/passwd
在文件/etc/passwd
包含字符串bash的行。
grep bash /etc/passwd
grep "Gnome Display Manager" /etc/passwd
root:x:0:0:root:/root:/bin/bash
myfreax:x:1000:1000:myfreax:/home/myfreax:/bin/bash
grep 排除与反转匹配
要仅打印与搜索模式不匹配的行,可以使用grep
命令的-v
或--invert-match
选项进行反转的匹配。
注意grep
会区分大小写。这意味着大写和小写被视为不同的字符。要在搜索时忽略大小写,使用-i
选项调用grep
。
如果搜索字符串包含空格,只需要将其括在单引号或双引号中。grep就会搜索空格,你也可以使用正则表达式表示空格的匹配。
例如命令ps aux | grep fnord | grep -v grep
在搜索进程的时候排除自身的进程。
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
myfreax:x:1000:1000:myfreax:/home/myfreax:/bin/bash
grep 搜索标准输入
除了指定搜索文件之外,您还可以将另一个命令的标准输出传递给grep
命令通过管道,然后仅打印与指定模式匹配的行。
例如命令ps -ef | grep www-data
使用ps
命令列出所有进程然后通过管道传递grep
命令搜索www-data
用户运行的进程。
如果在搜索结果不多的时候,你很容易就会发现ps -ef | grep www-data
命令的标准输出还包含当前grep
进程的信息。
如果您不希望打印grep进程的信息,可将标准输出再次通过管道传递到另一个grep
实例排除grep
进程的输出。例如命令ps -ef | grep www-data | grep -v grep
。
ps -ef | grep www-data
ps -ef | grep www-data | grep -v grep
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命令的-r
或者-R
选项。gerp命令将以文件路径为前缀打印匹配的行,并使用冒号:
分隔。
grep命令的-r
和-R
选项的不同之处在于,-r
选项仅递归目录和普通文件,但不包括符号链接,也就是软链接。-R
选项则包括软链接。
例如命令grep -r myfreax.com /etc
将在/etc
目录内搜索包含myfreax.com
字符串的所有文件。
grep -r myfreax.com /etc
grep -R myfreax.com /etc
grep 仅打印文件名
默认gerp命令将以文件路径为前缀打印匹配的行,并使用冒号:
分隔。要仅打印包含匹配模式的文件名,可以使用grep
命令-l
/--files-with-matches
选项。
例如命令grep -l myfreax.com *.conf
将在当前工作目录搜索以.conf
结尾的文件。
并仅打印包含字符串myfreax.com
的文件名称。你也可以组合-l
选项与-R
选项进行递归搜索文件。
grep -l myfreax.com *.conf
grep -Rl myfreax.com /tmp
tmux.conf
haproxy.conf
grep 不区分大小写
默认情况下grep
命令区分大小写。这意味着将大写和小写字符视为不同的字符。要在搜索时忽略大小写,请使用grep命令的-i
/--ignore-case
选项。
例如命令grep Zebra /usr/share/words
将搜索Zebra
。但是,如果使用-i
选项执行不区分大小写的搜索,则它将同时匹配大小写字母。
grep Zebra /usr/share/words
grep -i Zebra /usr/share/words
zebra
zebra's
zebras
grep 搜索单词
在搜索gnu时,grep
命令还将打印gnu嵌入在较大字词的行,例如cygnus
或magnum
。
单词字符包括a-z
,A-Z
和0-9
和下划线_
。所有其他字符都被视为非单词字符,例如$
等。
要仅搜索指定字符串是整个单词的行,请使用grep命令的-w
/--word-regexp
选项。
grep gnu /usr/share/words
grep -w gnu /usr/share/words
gnu
grep 打印行号
要打印与模式匹配的行号,请使用grep命令的-n
/--line-number
选项。grep
命令将以行号作为前缀打印匹配的行。
例如命令grep -n 10000 /etc/services
在/etc/services
文件搜索包含1000数值的行。
grep -n 10000 /etc/services
393:webmin 10000/tcp
grep 统计匹配行数
要仅打印与搜索模式匹配的行数,请使用grep
命令的-c
/--count
选项。
例如命令grep -c '/usr/bin/zsh' /etc/passwd
统计以/usr/bin/zsh
为默认shell的用户数量。
grep -c '/usr/bin/zsh' /etc/passwd
4
grep 指定多个搜索模式
grep命令允许你使用或运算符|
组合多个搜索模式搜索文件。默认情况下,grep
将模式解释为基本正则表达式。
当你在基本正则表达式中使用使用OR运算符|
时,必须使用反斜杠\
进行转义。因为shell会将|
解释为Shell管道。
如果在grep命令指定选项-E
/--extended-regexp
使用的是扩展正则表达式,则不应对或运算符|
进行转义。
在下面的示例中,我们在Nginx错误日志文件中搜索单词fatal
,error
和critical
匹配的行。
grep 'fatal\|error\|critical' /var/log/nginx/error.log
grep -E 'fatal|error|critical' /var/log/nginx/error.log
grep 不打印标准输出
grep
命令的-q
/--quiet
选项指示不向终端写入任何内容,通常是标准输出。如果搜索到匹配的行,grep
命令的退出代码是0。
这样就可以在Shell脚本使用if
语句和grep静默模式,判断文件是否包含指定的字符串。
if grep -q PATTERN filename
then
echo pattern found
else
echo pattern not found
fi
grep 正则表达式基础
GNUgrep
支持三种正则表达式语法,Basic、Extended和Perl-compatible。默认情况下,grep
将模式解释为Basic正则表达式。
当你在正则表达式中使用使用OR运算符|
时,必须使用反斜杠\
进行转义。因为shell会将|
解释Linux管道。
如果你使用的扩展正则表达式,则|
不不需要转义,即不需要反斜杠\
,-E
选项指示grep
命令使用扩展正则表达式。
^
符号匹配行首,$
符号匹配行尾,.
符号以匹配任意单个字符,[ ]
中括号匹配指定范围的字符,[^ ]
以匹配非中括号内的任意字符。
例如命令grep -Ewv 'nologin|bash' /etc/passwd
和grep -wv 'nologin\|bash' /etc/passwd
是等效的,前者使用的是扩展表达式,后者使用基本正则表达式。
grep -Ewv 'nologin|bash' /etc/passwd
grep -wv 'nologin\|bash' /etc/passwd
grep 打印匹配行前半与后半部分
要在匹配行之前打印指定数量的行,请使用-B
/--before-context
选项。要在匹配的行之后打印指定数量的行,请使用-A
/--after-context
选项。
例如,要在匹配的行之前打印前五行,请运行命令grep -B 5 root /etc/passwd
。
命令grep -A 5 root /etc/passwd
在匹配的行之后显示尾随五行。这个有点类似在指定位置截断。
grep -B 5 root /etc/passwd
grep -A 5 root /etc/passwd
grep 电子邮件地址
-o
选项用于仅打印匹配的字符串。
grep -E -o "\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}\b" file.txt
grep IP地址
-o
选项用于仅打印匹配的字符串。
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
结论
grep
命令允许您使用指定的模式或者正则表达式搜索文件。如果找到匹配的行,grep将打印包含指定模式的行。
请访问Grep用户手册页面,要了解Grep的更多信息。如果您有任何问题或反馈,请随时发表评论。