说起Linux操作系统中的grep
命令,或许没有人会不知道。在我看来,grep
命令是Linux操作系统上最强大的工具之一,正如你无时无刻不在使用它。无论是从文件中找到匹配的行,又或者是从终端输出中获取指定信息,都离不开对 grep
的使用。
了解一个工具的使用,还是先看这个工具的man手册会告诉我们什么。
# man grep
GREP(1) General Commands Manual GREP(1)
NAME
grep, egrep, fgrep - print lines matching a pattern
SYNOPSIS
grep [OPTIONS] PATTERN [FILE...]
grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...]
DESCRIPTION
grep searches the named input FILEs (or standard input if no files are named, or if a
single hyphen-minus (-) is given as file name) for lines containing a match to the given
PATTERN. By default, grep prints the matching lines.
In addition, two variant programs egrep and fgrep are available. egrep is the same as
grep -E. fgrep is the same as grep -F. Direct invocation as either egrep or fgrep is
deprecated, but is provided to allow historical applications that rely on them to run
unmodified.
...
手册中提到,grep
工具还有两个孪生兄弟,分别是 egrep
和 fgrep
。其中,egrep
相当于 grep -E
的用法,使用的是扩展形式的正则表达式;fgrep
相当于 grep -F
的用法,根据固定模式进行内容匹配。
参数详解
对于任何的Linux操作系统,你可以很轻松的找到/etc/passwd
文件,以下的多数演示将会以该文件进行演示。以下为用户的部分信息
#cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
grep
命令的格式相对比较简单。完整的命令格式如 grep [OPTIONS] PATTERN [FILE...]
,其中 [OPTIONS] 选项提供了众多的参数,如下
-
-E, --extended-regexp
: 使用正则规则匹配相应的内容,相当于egrep
(一种并不推荐的用法)
如果需要找到包含root用户和adm用户的行,可以通过grep -E "root|adm" /etc/passwd
来查找所有满足的行
#grep -E "root|adm" /etc/passwd
root:x:0:0:root:/root:/bin/bash
adm:x:3:4:adm:/var/adm:/sbin/nologin
-
-F, --fixed-strings, --fixed-regexp
: 将范本样式看作固定的字符串列表
-
-e PATTERN, --regexp=PATTERN
: 指定多个匹配模式。多个模式以 -e pattern1 -e pattern2 格式
# grep -e root -e adm /etc/passwd
root:x:0:0:root:/root:/bin/bash
adm:x:3:4:adm:/var/adm:/sbin/nologin
-
-f FILE, --file=FILE
: 指定范本文件。范本文件中的格式为每行一个范本,根据范本文件中的内容匹配内容
# cat grep-file
adm
root
# grep -f grep-file /etc/passwd
root:x:0:0:root:/root:/bin/bash
adm:x:3:4:adm:/var/adm:/sbin/nologin
-
-i, --ignore-case
: 搜索模式时忽略大小写
# cat grep-file
adm
root
LOGGER
Logging
# grep -i log grep-file
LOGGER
Logging
-
-v, --invert-match
: 对搜索到的结果进行取反,只输出符合匹配模式以外的行
# grep -v root /etc/passwd
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
-
-w, --word-regexp
: 以单词作为匹配模式。例如,指定-w log
将只能匹配到log
, 不能匹配到logg
、logging
等。
# grep -w Logg grep-file
# grep -w Logging grep-file
Logging
-
-x, --line-regexp
: 以整行作为匹配模式。例如,指定-x log
将只能匹配log
,不能匹配到logs
、log err
等。
# cat grep-file
adm
root
LOGGER
Logging
Logging record
# grep -x Logging grep-file
Logging
-
-c, --count
: 返回匹配到的行数,代替返回匹配到的内容
# grep -c Log grep-file
3
-
-L, --files-without-match
: 根据输入文件匹配指定模式时没有合适的匹配结果时输出文件名称,倘若在输入文件中匹配到了内容,不会输出文件名
# grep -L root grep-file
# grep -L name grep-file
grep-file
-
-l, --files-with-matches
: 根据输入文件匹配指定模式时匹配到合适的结果时输出文件名称,与-L
用法相反
# grep -l name grep-file
# grep -l root grep-file
grep-file
-
-m NUM, --max-count=NUM
: 最多返回匹配到的记录数
# grep -m 2 Log grep-file
Logging
Logging record
-
-o, --only-matching
: 仅输出匹配到的内容。例如,用roo
匹配root
时,将只匹配到roo
。通常和-n
配合使用
# grep -o roo -n grep-file
2:roo # 2 为行号
# grep -o root -n grep-file
2:root
-
-q, --quiet, --silent
: 静默模式,不会向标准输出中写入任何东西(简单点说就是终端不会返回任何内容),一旦匹配到任何东西或出现错误,将以0
的返回值退出
# grep -o root -n -q grep-file
# echo $?
0
-
-s, --no-messages
: 抑制出错信息。终端将不会打印标准错误
# grep -s root grep-
# grep root grep-
grep: grep-: 没有那个文件或目录
-
-b, --byte-offset
: 输出匹配到的内容及开始字符的偏移量。偏移量从文件头部开始,初始值为 0
# cat grep-file
adm
root
LOGGER
Logging
Logging record
Loggingrecord
# grep -b root grep-file
4:root
# grep -b ad grep-file
0:adm
-
-H, --with-filename
: 匹配到内容时将文件名称与匹配到的内容成对输出。对于从多个文件中匹配内容非常有帮助
# grep -H root /etc/passwd grep-file
/etc/passwd:root:x:0:0:root:/root:/bin/bash
/etc/passwd:operator:x:11:0:operator:/root:/sbin/nologin
grep-file:root
-
-n, --line-number
: 匹配到结果时输出对应的行
# grep -n root grep-file
2:root
-
-A NUM, --after-context=NUM
: 输出匹配到的行及行后的多少行。
# grep -A 2 -n root grep-file
2:root
3-LOGGER
4-Logging
-
-B NUM, --before-context=NUM
: 输出匹配到的行及之前的多少行
# grep -B 2 -n root grep-file
1-adm
2:root
-
-C NUM, -NUM, --context=NUM
: 输出匹配到内容的前后两行
# grep -C 2 -n root grep-file
1-11111
2-adm
3:root
4-LOGGER
5-Loggin
-
-r, --recursive
: 在指定目录下递归查找所有文件中满足匹配条件的。指定目录下存在符号链接文件的,仅当指定符号链接时才会在符号链接对应的目录下查找
-
-R, --dereference-recursive
: 与-r
参数用法基本一致,区别在于当指定目录下存在符号链接文件时,会主动在符号链接文件对应的目录下查找 (参考自: grep -r 和 -R有什么区别)
正则部分
了解 grep
的常用参数可以在工作中解决绝大部份的问题,但在一些情况下,需要对过滤出的内容按照某种规则进行精确匹配,还需要配合正则使用。以下介绍了几种常用的正则语法
-
^ pattern
: 匹配以pattern格式开头的行
# grep -E "^a" grep-file
adm
-
pattern $
: 匹配以pattern模式结尾的行
# grep -E "record$" grep-file
Logging record
Loggingrecord
-
pattern +
: 匹配指定模式一次或多次
# grep -E gr+ grep-file
Loggingrecord
-
pattern *
: 匹配pattern模式结尾的所有内容
# grep -E ad* grep-file
adm
-
pattern {n}
: 匹配pattern模式n次
# grep -E g{2} grep-file # 匹配至少包含2个g的单词
Logging
Logging record
Loggingrecord
-
pattern {n,}
: 匹配pattern模式n次或更多次
# grep -E o{1} grep-file
root
Logging
Logging record
Loggingrecord
# grep -E "o{2,}" grep-file
root
-
pattern {,m}
: 匹配pattern模式最多m次
# cat grep-file
adm
root
LOGGER
Logging
Logggggggggggg
Logging record
Loggingrecord
# grep -E "g{,3}i" grep-file
Logging
Logging record
Loggingrecord
-
pattern {n,m}
: 匹配pattern模式最少n次,最多m次
# grep -E "gg{1,3}i" grep-file
Logging
Logging record
Loggingrecord