grep 用法详解
三大文本处理工具之 grep。
语法格式
grep [选项] "匹配模式" [文件]
常用功能选项
-
-v
:反向选择 -
-n
:显示行号 -
-w
:完整匹配一个单词,而不能只是匹配单词中的片段 -
-c
:统计有多少文本行被匹配到了。 -
-o
:只显示被模式匹配到的字符串。 -
--color
:将匹配内容高亮显示。 -
-i
:忽略大小写。 -
-E
:开启扩展(Extend)的正则表达式。
多行显示:
多行显示,适用于显示配置内容,例如 nginx.conf 配置,需要查看所有的目录配置,那么可以使用多行显示选项查看配置的上下文。
-
-A n
:显示匹配的字符串及后面 n 行。 -
-B n
:显示匹配的字符串及前面 n 行。 -
-C n
:显示匹配的字符串及前后 n 行。
查找文件的两种形式
直接指明文件。
grep "root" /etc/passwd
通过管道输入
cat /etc/passwd | grep "root"
同时匹配多个条件
使用管道,多个条件过滤
grep -v root /etc/passwd | grep -v nologin
查找整个目录
文本处理工具能够处理一个文件,如果要在大量的文件之中进行查找执行内容,一个个文件的匹配就太慢了,可以使用 grep 直接查找整个目录。
# 匹配当前目录下的所有文件,是否包含 test 字符串,将返回匹配的文本行
grep -r "test" *
# 匹配所有文件,返回包含目标行的文件名称
grep -l -r "test" *
理解基本例子
例1:查找当前目标下,含有 prog 前缀的文件内容中,包含 test 字符串的部分
grep test prog*
例2:递归遍历目标下,包含指定文件的内容。
grep -r update /etc/acpi
例3:反向查找,文件内容
grep -v test *test*
匹配模式
基本匹配的例子:
统计 test.file 文件中 test 字符串的个数。
grep -c "test" test.file
匹配模式,是基于正则表达式的,可以匹配字符,如下:
-
.
任意字符 -
[abc]
匹配 abc 字符中的一个 -
[a-zA-Z]
匹配字母表 52 个字母中的一个 -
[^123]
匹配以字符 123 中的一个开头的字符串
预定义字符集:
-
A-Za-z
等价于[:alpha:]
-
0-9
等价于[:digit:]
-
A-Za-z0-9
等价于[:alnum:]
-
tab, space
等价于[:space:]
-
A-Z
等价于[:upper]
-
a-z
等价于[:lower]
- 标点符号集合 等价于
[:punct:]
例子:
grep "hello" [^[A-Z]][[a-z]] test.file
# 等价于
grep "hello [^[:upper:]][[:digit:]]" test.file
控制匹配次数
上述匹配模式,都是对字符匹配一次。我们可以给其添加匹配次数规则。
-
\{m,n\}
:匹配前面出现的字符 m 到 n 次。 -
\?
:匹配前面出现的字符 0 次或者 1次。 -
*
:匹配前面的内容出现任意次,可以是 0 次。
例子:
# 匹配任意 xxsh 字符串
grep "/.\{0,2\}sh" /etc/passwd
# 匹配 xxsh 四字单词
grep -w ".\{0,2\}sh" /etc/passwd
位置锚定
位置锚定,包括以下类型:
-
^
:锚定行首 -
$
:锚定行尾 -
^$
:匹配空白行 -
\b或\<
:锚定单词的词首 -
\b或\>
:锚定单词的词尾 -
\B
:与\b作用相反。
分组引用
grep 中分组的基本原理,和正则匹配式一样,使用括号进行包裹。
能够将字符串作为一个整体,方便后面进行使用。包括以下基本用法:
-
\1
:引用第一个括号匹配的内容。 -
\2
:引用第二个括号匹配的内容。 -
\n
:引用第 n 个括号匹配的内容。
例子:
匹配一个首尾的字符/字母相同的行。
grep "^\([[:alpha:]]\).*\1$" test.file
可以看到上述第一个括号中,代表了第一个字母的内容。后面定义了以相同的字母进行结尾。
拓展匹配的正则模式
在上面的例子中,我们可以看到,由于在字符串中需要对特殊字符进行转移,所以需要使用大量反斜杠。例如 \(
,不方便并且难以阅读。
使用 -e
选项或者 egrep
工具可以默认转义,不再使用反斜杠对特殊符号进行修饰。
如下:
-
\{m,n\}
等价于{m,n}
-
\?
等价于?
例子
匹配四字字符串,以下三种方式等价。
grep ".\{0,2\}sh" /etc/passwd
grep -e ".{0,2}sh" /etc/passwd
egrep ".{0,2}sh" /etc/passwd
正则的多种条件
多种条件常用于特定规则语句的匹配,比如电话号码等等。我们使用 |
符号对每个字符单元进行指定规则。
例子:
匹配小于 100 以下的所有数字。
egrep "[0-9]|[1-9][0-9]" test.file