Linux常用命令--grep与egerp

摘要

  • grep与egrep的使用

  • 本文基于CentOS8(x86_64)

grep

  • grep命令是linux中一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。

  • 语法

1
grep [option] pattern files
  • 常用参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
功能参数	    解释
-a 选项会显示所有匹配行,包括空行。
-c 输出匹配到的行数,功能等同于wc -l
-i 正则表达式忽略大小写
-l 查询多文件时只输出包含匹配字符的文件名
-h 查询多文件时不显示文件名
-n 显示匹配行的行号
-s 不显示文件不存在或无匹配文本的错误信息
-v 显示不包含匹配文本的行
-w 强制 PATTERN 仅完全匹配字词
-x 强制 PATTERN 仅完全匹配一行
-e 用 PATTERN 来进行匹配操作,通常用来匹配多个条件或者PATTERN中含有参数项的
-o 仅显示匹配的字符串本身,一行中有多个匹配,会分行显示
-r 在指定目录下递归查找所有文件中匹配关键字的行
-A 同时显示匹配行的后几行
-B 同时显示匹配行的前几行
-C 同时显示匹配行的前几行和后几行
-NUM 同时显示匹配行的前几行和后几行,等同于 -C,如:-C 2 === -2
-G 基本正则表达式,此为预设
-E 扩展正则表达式,等同于egrep
-P Perl 正则表达式
  • 示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# 匹配关键字key,忽略大小写
grep -i key file

grep "^#" file : 显示所有行首是#的行
^ : 正则,以什么开头的行
$ : 正则,以什么结尾的行

grep -v "^#" file : 显示所有行首不是#的行
-v : 找出与所给关键字不匹配的行

# 字符匹配
grep [A] file : 行中内容包含给定的字符
[ ] : 匹配单个字符
grep [^A] file : 行中内容不包含给定的字符
[^] : 不匹配单个字符
grep [A-Z] file : 行中内容包含给定的字符范围中的任何一个
[-] : 匹配范围字符

grep [ABC] file : 行中内容包含给定的字符列表中的任何一个
grep [^ABC] file : 匹配除方括号中字符外的所有字符

# 字符类描述: 注意使用时外面要加[]
[:alnum:] 字母数字集 “a-z A-Z 0-9”
[:alpha:] 字母集合 “a-z A-Z”
[:blank:] 空格或制表键
[:cntrl:] 任何控制字符
[:digit:] 数字集合 “0-9”
[:graph:] 任何可视字符(无空格)
[:lower:] 小写字母 “a-z”
[:print:] 非控制字符
[:punct:] 标点字符
[:space:] 空格
[:upper:] 大写字母 “A-Z”
[:xdigit:] 十六进制数字 “0-9 a-f A-F”

# 示例
#搜索开头不是英文字母的行
grep ^[^[:alpha:]] file === grep ^[^a-zA-Z] file
# 搜索非空行
grep -v "^$" file : 搜索非空行,严格来讲这个不准确,不能去除行内容只有空格或者制表符的行
grep [^[:blank:]] file : 搜索非空行,去除行内容只有空格或者制表符的行

grep key file -A 10 : 显示关键字行及其后面的10行
-A : After

grep key file -B 10 : 显示关键字行及其前面的10行
-B : Before

grep key file -2 : 显示关键行及其上两行和下两行
-num : 显示上下各num行

# -E 开启扩展正则表达式
grep -E "^#" file  #打印所有注释行
-E : 支持扩展正则表达式

grep -E 'key1|key2' -n -i file : 查找包含任意关键字的行,并显示行号
-n : 显示行号
-i : 不区分大小写

grep key -c file : 查找关键字匹配的行数
-c : 只输出匹配行的计数

# 这个命令非常有用,可以快速定位关键字所在的文件位置
grep 'key' -r dir : 在目录下递归查找文件内容包含关键字的文件路径及其所含关键字的内容
-r : 递归查找

grep 'key' -l *.log : 打印包含关键字的文件名称
-l : 在多个文件中查找关键字,并打印文件名称

# 把key当做一个完整的单词来进行匹配,忽略那些部分匹配的行,比如 to只能匹配to,不能匹配tom
grep -w key file

# 如果不用 -e 会无法解析命令,即便加上双引号也不行 "-vb-"
grep -e -vb- file

# 标准正则,匹配key1 或者 匹配key2,正则中的特殊符号需要转义
grep -e key1 -e key2 file
# 扩展正则
grep -Ee key1 -Ee key2 file

# 需要同时匹配key1和key2
grep key1 file | grep key2

# -o 可以用来统计找到多少个匹配项
grep -E "ro+t" /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
# 每个匹配项占一行
grep -Eo "ro+t" /etc/passwd
root
root
root
root

小贴士

grep的推荐使用命令为

1
grep -aiE "key" file

egrep

  • egrep命令用于在文件内查找指定的字符串,egrep执行效果与"grep -E"相似,使用的语法及参数可参照grep指令,与grep的不同点在于解读字符串的方法。

  • egrep命令为 grep 的扩充版本, 改良了许多传统 grep 不能或不便的操作,比如:

    • grep 使用 ?+ 时需要转义, 但egrep不需要。
    1
    2
    3
    grep "[0-9]\+" test.txt
    grep -E "[0-9]+" test.txt
    egrep "[0-9]+" test.txt
    • grep 使用 a|b(abc|xyz) 这类"或一"比对时需要对|进行转义, 但egrep不需要。
    1
    2
    3
    4
    5
    6
    7
    grep "a\|s" test.txt
    grep -E "a|s" test.txt
    egrep "a|s" test.txt

    grep "\(a\|s\)" test.txt
    grep -E "(a|s)" test.txt
    egrep "(a|s)" test.txt
    • grep在处理 {n,m} 时, 需用 \{ \} 进行转义, 但egrep不需要。
    1
    2
    3
    grep "[0-9]\{3\}" test.txt
    grep -E "[0-9]{3}" test.txt
    egrep "[0-9]{3}" test.txt
  • 语法

1
egrep [范本模式] [文件或目录]
  • 示例

1
2
3
4
egrep 'key1|key2|key3' file : 查找包含任意关键字的行
egrep 'a+' file : 查找包含一个或多个a的行
egrep '(abc)' file : 包含abc整体的行
egrep '(abc)+' file : 包含一个或多个abc整体的行

linux正则表达式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
基础正则表达式	    解释
^ ^word表示以word开头的内容
$ word$表示以word结尾的内容
^$ 表示空行
. 代表且只能代表任意一个字符
\ 转义字符
* 重复之前的字符0或多次
.* 匹配任意多个字符
[abc] 匹配abc其中的任意一个
[^abc] 匹配未包含在[abc]内的任意一个字符
[a-z] 匹配a-z其中的一个字符,[0-9]匹配任意数字

# grep -E 或者 egrep,grep使用时要转义特殊字符
扩展正则表达式 解释
{m,n} 匹配前一个字符m到n次,注意grep使用时,{}要加转义字符\{\}
{m} 匹配字符m次
{m,} 匹配字符至少m次
+ 匹配前一个字符1次或者多次,最少一次,如 wo+d,可以匹配 "wood" "woood" "woooooood"等字符串
? 重复前一个字符0次或者1次,如 bes?t,可以匹配 "bet" 和 "best" 两个字符串
| 同时过滤多个字符,如 of|is|on,匹配包含 "of" 或者 "if" 或者 "on" 的字符串
() 分组,将1个或多个字符捆绑在一起,当做一个整体进行处理,如 t(ad|ef)st,可以匹配 "tadst" 与 "tefst" 两个字符串
分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量中,这些变量的命名方式为:\1,\2,\3....,如:sed -r 's/(^love)able/\1rs/' example 
()+ 辨别多个重复的组,如 A(xyz)+C ,可以匹配 开头是"A"结尾是"C",中间有一个以上的"xyz"的字符串

# grep -P,不支持egrep
Perl 正则表达式 解释
\t 匹配制表符
\n 匹配换行符
\s 匹配空白字符,空格、制表符\t、换行符\r和\n等
\S 匹配非空白字符
\d 匹配数字[0-9],如:grep -P "\d" test.txt
\D 匹配非数字[^0-9]
\w 匹配字母数字下划线[a-zA-Z0-9_]
\W 匹配非字母数字下划线[^a-zA-Z0-9_]
(?:xxx) 匹配xxx,但是不会被正则表达式引擎记录于内部的变量中,也就是无法通过\1,\2,\3....获得