[TOC]
介绍
grep (global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来
- egrep和fgrep的命令只跟grep有很小不同
- egrep是grep的扩展,支持更多的re元字符
- fgrep就是fixed grep或fast grep,它们把所有的字母都看作单词,也就是说,正则表达式中的元字符表示回其自身的字面意义,不再特殊
MacOS使用Free-BSD版本的grep,区别是很UNIX很死板
linux使用GNU版本的grep
它功能更强,可以通过-G、-E、-F命令行选项来使用egrep和fgrep的功能
标准命令
grep [-acinv] [--color=auto] '[搜寻字符串]' filename
选项与参数:
-V : 输出grep指令的当前版本
-a : 将 binary 文件以 text 文件的方式搜寻数据
-c : 计算找到 '搜寻字符串' 的次数
-i : 忽略大小写的不同,所以大小写视为相同
-n : 输出行号
-v : 反向选择,亦即显示出没有 '搜寻字符串' 内容的那一行
--color=auto : 可以将找到的关键词部分加上颜色的显示
-An : 之后n行 after
-Bn : 之前n行 before
-Num : 例如 -5 就是前后5行
-I : 忽略二进制文件
-r -R : 递归查找
-L : 只输出匹配到的文件
-G : 基础正则匹配
-E : 扩展正则匹配 等效 egrep
-F : 匹配多字符串模式只能找固定的文本 等效 fgrep
搜索关键字
# 将/etc/passwd 中含有 root 的行都显示出来
grep root /etc/passwd
# 将/etc/passwd,有出现 root 的行取出来,同时显示这些行在/etc/passwd的行号
grep -n root /etc/passwd
# 将/etc/passwd,将没有出现 root 的行取出来
grep -v root /etc/passwd
# 将/etc/passwd,将没有出现 root 和nologin的行取出来
grep -v root /etc/passwd | grep -v nologin
# 用 dmesg 列出核心信息,再以 grep 找出内含 eth 那行,要将捉到的关键字显色,且加上行号来表示
sudo dmesg | grep -n --color=auto 'eth'
# dmesg 列出核心信息,筛选出带有 `eth`的信息,列出 前2行(B before),后3行(A after)数据
sudo dmesg | grep -n 'eth' -A3 -B2
# dmesg 列出核心信息,筛选出带有 `eth`的信息,列出 前后5行数据
sudo dmesg | grep -5 'eth'
根据文件内容递归查找目录
# 当前目录中搜索带有 "echo" 的文件
grep "echo" *
# 递归当前目录及其子目录下搜索带有 "echo" 行的文件
grep -r "echo" *
# 递归当前目录及其子目录下搜索带有 "echo" 行的文件, 但是不显示匹配的行,只显示匹配的文件
grep -r -L "echo" *
# 递归文件夹 "my/log" 打印含有 "echo" 的文件行路径,行号 和内容
grep -rIn "my/log" "echo"
# 递归某一类*.log 文件中含有 "echo"行的,并且打印行号
find . -name "*.log" -exec grep -n "echo" {} \;
# 也可以使用xargs
find . -name "*.log" | xargs grep --color=auto -In "echo"
grep 正规表达式用法
grep 支持的就是 perl 风格的正则, 出现正则不识别的问题使用 egrep
[]
通配单一字节,无论[]中有多少内容,都是当一个占位来看待
^
反向选则,也就是非这个字符串 比如一定不能有小写字符 [^a-z]
^$
行首 行尾符 只在非() 中生效 可以用于定位字符出现的位置
.
表示任意字节,也就是通配符
*
表示复数字节,比如文件名称全通配就是 *.*
任意后缀通配 .*
如果该字节组是连续的,例如大写英文/小写英文/数字等等, 就可以使用[a-z],[A-Z],[0-9]等方式来书写
限定字符的范围
- 可以使用
[a-z],[A-Z],[0-9]
等方式来书写 - 那么如果我们的要求字串是数字与英文就将他全部写在一起,变成:
[a-zA-Z0-9]
- 不想要开头是英文字母
^[^a-zA-Z]
- 开头是小写字节
^[a-z]
- 行尾结束为小数点 或者某种后缀
\.$
(\.so)$
任意一个字节 .
与重复字节 *
. (小数点):代表『一定有一个任意字节』的意思
* (星号):代表『重复前一个字符, 0 到无穷多次』的意思,为组合形态
- 类似 good gred 之类的字符串
g..d
- 两个 o 以上的字串
ooo*
- g 开头与 g 结尾的行,当中的字符可有可无
g.*d
限定连续 RE 字符范围 {}
这个限定范围必须和 .
*
配合使用, 且因为在shell中,{}
必须被转意才可以使用
- 找到两个 o 的字串
o\{2\}
- g 后面接 2 到 5 个 o ,然后再接一个 d 的字串
go\{2,5\}d
- 2 个 o 以上的 goooo....d
go\{2,\}d
egrep
使用扩展grep的主要好处是增加了额外的正则表达式元字符集,这在匹配中文时常用
比如打印所有包含info或error的行 'info|error'
grep就不会打印
如果在扩展元字符前面加\,grep会自动启用扩展选项-E,比如上面的匹配,这样就合适了
'info\|error'
- 搜索所有包含0个或1个小数点字符的行
egrep '2\.?[0-9]
- 找到一个或者多个连续的error的行
egrep '(error)+'
fgrep
查询速度比grep命令快,它只能找固定的文本,而不是规则表达式
# 输出在~/logs/my.log中包含error的行
fgrep 'error' ~/logs/my.log
扩展
UNIX Linux 平台处理文本的三大件 grep
sed
awk
建议熟练使用他们
查询帮助文档
man sed