Linux 文本三剑客 - Grep
grep 是一个最初用于 Unix 操作系统的命令行工具。在给出文件列表或标准输入后,grep 会对匹配一个或多个正则表达式的文本进行搜索,并只输出匹配(或者不匹配)的行或文本。
1970 年代,Unix 之父 Ken Thompson 将正则表达式引入到 Unix 中文本、编辑器 ed 和 grep 命令中,由此正则表达式普及开来。
1980 年后,perl 语言对 Henry Spencer 编写的库,扩展了很多新的特性。1997 年开始,Philip Hazel 开发出了PCRE(Perl Compatible Regular Expressions),它被 PHP 和 HTTPD 等工具采用。
正则表达式应用极其广泛,Shell 中处理文本的命令、各种高级编程语言都支持正则表达式。
1、正则表达式分类
BRE
基本正则表达式,grep、sed、vi 等软件支持。vim 有扩展。ERE
扩展正则表达式,egrep(grep -E)、sed -r 等。PCRE
几乎所有高级语言都是 PCRE 的方言或者变种。
2、Grep 命令
$ grep --help 用法: grep [选项]... PATTERN [FILE]... 选项: -v 显示不被匹配的行(取反) -i 忽略大小写 -n 输出的同时打印行号 -c 统计匹配的行数 -o 仅显示匹配到的字符串 -q 静默模式,不输出任何信息,常用于判断 -e 实现多个选项之间的逻辑 or 关系 -w 匹配整个单词 -B 打印以文本起始的 NUM 行 -A 打印以文本结尾的 NUM 行 -C 打印以文本前后各 NUM 行 -E 使用 ERE -F 相当于 fgrep,不支持正则
2.1 字符匹配
字符 | 匹配 |
. | 匹配除换行符外任意一个字符 |
[abc] | 匹配集合内的任意一个字符 |
[^abc] | 匹配集合外的任意一个字符 |
[a-z] | 匹配字符范围内的任意一个字符 |
[^a-z] | 匹配字符范围外的任意一个字符 |
\b | 匹配单词的边界 |
\B | 不匹配单词的边界 |
[[:alnum:]] | 匹配字母和数字 |
[[:alpha:]] | 匹配字母 |
[[:lower:]] | 匹配小写字母 |
[[:blank:]] | 匹配空白字符 |
[[:space:]] | 匹配水平和垂直的空白字符 |
[[:cntrl:]] | 匹配不可打印的控制字符 |
[[:digit:]] | 匹配十进制数字 |
[[:graph:]] | 匹配可打印的非空白字符 |
[[:print:]] | 匹配可打印字符 |
[[:punct:]] | 标点符号 |
实例:
$ cat demo.txt Abc 123, def 456. $ cat demo.txt | grep -io "[a-z][a-z][a-z]" Abc def $ cat demo.txt | grep -io "[[:digit:]][[:digit:]][[:digit:]]" 123 456
2.2 匹配次数
用在要指定次数的字符后面,指定前面的字符要出现的次数。
字符 | 匹配 |
* | 匹配前面的字符任意次,包括 0 次 |
.* | 匹配任意长度的任意字符 |
\? | 匹配其前面的字符 0 或 1 次 |
\+ | 匹配其前面的字符至少 1 次 |
\{n\} | 匹配前面的字符 n 次 |
\{m,n\} | 匹配前面的字符至少 m 次,至多 n 次 |
\{,n\} | 匹配前面的字符至多 n 次 |
\{n,\} | 匹配前面的字符至少 n 次 |
实例:
$ cat demo.txt Abc 123, def 456. $ cat demo.txt | grep -io "[[:digit:]]\{3\}" 123 456
2.3 位置锚定
字符 | 位置 |
^ | 行首锚定,用于模式的最左侧 |
$ | 行尾锚定,用于模式的最右侧 |
^$ | 匹配空行 |
^[[:space:]]*$ | 匹配空白行 |
\< 或 \b | 词首锚定,用于单词模式的左侧 |
\> 或 \b | 词尾锚定,用于单词模式的右侧 |
实例:
$ cat demo.txt Abc 123, def 456. $ cat demo.txt | grep -io "^[a-z]\+" Abc
2.4 分组应用
使用小括号 \(\)
将一个或多个字符捆绑在一起,当做一个整体进行处理,例如:\(root\)\+
。
分组括号中模式匹配到的内容会被正则表达式引擎记录与内部变量中,这些变量的命名方式为:\1, \2, \3, … \1 表示从左侧起第一个左括号以及与之匹配右括号之间的模式所匹配到的字符。
实例:
$ echo "abcabcabc" | grep -o "[abc]\{3\}" abc abc abc $ echo "abcabcabc" | grep -o "\([abc]\{3\}\)\1\1" abcabcabc