Linux 内置工具 grep 使用手册
本文档介绍日常中使用grep的方法 "grep"是"Global RegularExpression Print"的首字母缩写, 使用过程中会涉及到正则表达式的使用 正则表达式的详细使用请查看正则表达式的文档
Table of Contents
本文档介绍日常中使用grep的方法
"grep"是"Global RegularExpression Print"的首字母缩写, 使用过程中会涉及到正则表达式的使用
正则表达式的详细使用请查看正则表达式的文档
简介
使用Linux系统的过程中, 必然会遇到需要使用grep的情况。grep是Linux系统内置的工具。
(BSD和Unix中内置了grep, Windows 系统中可以安装 wingrep 或者 Cygwin)
GNU grep存在4种查询模式:
- 基本正则表达式查询
- 扩展正则表达式查询
- 定长字符串查询
- Perl风格正则表达式查询
概念总览
grep可以从文件或者输出流中查询字符串。经常使用来捕获日志文件中特定的文本;查询文件中符合特定模式的内容(比如查询身份证号码);查询某个内容是否在文件中存在。
有两种方式给grep工具提供输入: 指定文件, 将文件内容作为输入;使用管道符"|"将其他命令的输出结果作为grep的输入。
grep适合"查询", 对于"查找并替换"的需求, 使用"sed"以及"awk"更加有效。
基本正则
使用如下格式进行正则模式的搜索:
grep [options] [regexp] [filename]
正则表达式包括两类字符:文本字符与元字符。想要查询等于元字符的字面意思的文本时,需要在元字符前面加上反斜杠"\"。比如"*"表示出现任意次数, "\*"表示"星号"
如果希望搜索的文本中含有"空格"(Unix系统以空格作为分隔命令选项的分隔符), 需要将正则表达式使用引号将其包括其中。
- 使用单引号,可以在引号范围内使用空格
- 使用双引号,还可以在引号范围内使用环境变量, 比如"$HOME"
- 使用重音符"
", 可以使用shell命令执行结果, 比如whoami`
正则匹配单个字符
| 元字符 | 名称 | 匹配功能 |
|---|---|---|
| . | 点 | 任意单个字符 |
| [...] | 字符类 | 匹配中任意括号中列举的字符 |
| [^...] | 负向字符类 | 匹配中任意括号中没有列举的字符 |
| \char | 转移字符 | 匹配反斜杠之后的字符 |
正则匹配位置
| 元字符 | 名称 | 匹配功能 |
|---|---|---|
| ^ | 托字符 | 行首 |
| $ | 美元符 | 行末 |
| < | 反斜杠+小于号 | 单词开头 |
| > | 反斜杠+大于号 | 单词结尾 |
正则匹配数量(量词)
| 元字符 | 名称 | 匹配功能 |
|---|---|---|
| ? | 问号 | 可选, 前一次表达式出现一次或不出现 |
| * | 星号 | 前一个表达式出现任意次数,包括零次 |
| + | 加号 | 前一个表达式出现1次或多次 |
| {N} | 精确次数匹配 | 匹配刚好N次 |
| {N,} | 最小次数匹配 | 至少匹配N次 |
| {min, max} | 指定次数区间匹配 | 匹配次数区间为[min, max] |
其他正则元字符
| 元字符 | 名称 | 匹配功能 |
|---|---|---|
| | | 替代选项 | 依次匹配给定表达式的某一个 |
| - | 英文破折号 | 表示范围 |
| (...) | 小括号 | 限制替代选项的范围 |
| \1, \2, ... | 反引用 | 匹配之前小括号匹配到的文本 |
| \b | 单词边界 | 匹配标记单词结束的一批符号 |
| \B | 反斜杠 | "\\"的替代写法 |
| \w | 单词字符 | 英文字符, 数字, 下划线 |
| \W | 非单词字符 | 非"英文字符, 数字, 下划线" |
| \` | buffer开头 | 匹配传给grep的buffer头 |
| \' | buffer结尾 | 匹配传给grep的buffer尾 |
POSIX 字符定义
| POSIX定义 | 字符定义的内容 |
|---|---|
| [:alpha:] | 任意英文字母表字符, 无论大小写 |
| [:digit:] | 任意数字字符 |
| [:alnum:] | 任意英文或数字字符 |
| [:blank:] | 空白符或Tab符 |
| [:xdigit:] | 十六进制字符, 包括所有数字字符和a-fA-F |
| [:punct:] | 任意标点符号 |
| [:print:] | 任意可打印字符(即控制字符之外的字符) |
| [:space:] | 任意空白符 |
| [:graph:] | 任意不是空白符的字符 |
| [:upper:] | 任意大写字母 |
| [:lower:] | 任意小写字母 |
| [:cntrl:] | 控制字符 |
用法示例:
grep [[:alpha:]] test.txt
grep基础
grep会查询一行直到看到新的一行。在新的一行会重新使用表达式匹配。
配合基本正则
使用命令: grep 或者 grep -G
匹配控制
-e pattern, --regexp=pattern
确保grep命令将模式文本识别为正则表达式
-f file, --file=file
指定文件
-i, --ignore
忽略大小写差异
-v, --invert-match
反向匹配, 返回文本中不包含指定模式的行
-w, --word-regexp
返回文本中完整匹配整个Word的行
-x, --line-regexp
返回文本中整个行内容刚好等于正则表达式的行基本输出控制
-c, --count
不是输出具体文本内容, 而是输出匹配到的行数目(不是匹配项的数目)
--color[=WHEN], --colour[=WHEN]
控制是否高亮, 值选项: auto, always, never
-l, --files-with-matches
不是输出具体文本内容, 而是输出匹配到指定模式的文件的文件名
-L, --files-without_match
不是输出具体文本内容, 而是输出没有匹配到指定模式的文件的文件名
-m NUM, --max-count=NUM
指定在匹配到NUM行符合模式的行后, 停止搜索
-o, --only-matching
只输出匹配到的内容, 即只输出高亮红色字体的部分
-q, --quiet, --silent
用于给shell脚本确认是否查询到指定文本. match到时返回0, 没有match到时返回1, 报错退出时返回2输出内容前缀控制
-H, --with-filename
输出内容前带文件名
-h, --no-filename
前缀不带文件名
-n, --line_number
输出行号
-T, --initial-tab
使用制表符来格式化输出. 比如:
test.txt: 1 :pattern
-z, --null
每个filename之后输出一个ASCII NUL(a zero byte). 用于shell脚本, 识别文件名结尾配合扩展正则
使用命令: grep -E regexp filename
比如: grep -E 'pat{2}ern|red' test.txt
等于命令: grep -E 'pat\{2\}ern\|red' test.txt样例:
| 基本正则模式 | 扩展正则模式 |
|---|---|
| '\(red\)' | '(red)' |
| 'a\{1,3\}' | 'a{1,3}' |
| 'behaviou?r' | 'behaviou?r' |
| 'pattern\+' | 'pattern+' |
定长字符串
使用命令: grep -F
性能
grep -E '(0|2|4)' filename
grep -E '[024]' filename第二个命令的性能会更好些。因为"|"的使用, 会导致一个行会执行多次搜索
另一个可能造成问题的时对分组的引用, "\1\2" (性能消耗可能是几何级数增长)
Tips and Tricks
分组的使用
测试文本
The red dog fetches the green ball.
The green dog fetches the blue ball.
The blue dog fetches the blue ball.
表达式 (red|green|blue).*(red|green|blue)可以匹配到每一行
但是 (red|green|blue).*\1只能匹配到第三行, 因为只有第三行满足了"(red|green|blue)重复出现"这个条件代码片
| 匹配目标 | 表达式 |
|---|---|
| IP addresses | \b[0-9]{1,3}(.[0-9]{1,3}){3} |
| MAC addresses | \b[0-9a-f]{2}(:[0-9a-f]{2}){5}\b |
| Email addresses | \b[a-z0-9]{1,}@*.(com |
| 美国Social Security numbers | '\b[0-9]{3}( |
搜索大文件
使用命令: find / -print | xargs grep `ABCDEFGH`
上述命令将搜索文件系统中的每个文件, 但是不会引发"打开太多文件"的错误