正则表达式(regular expression, RE)是一种字符模式, 用于在查找过程中匹配指定的字符. 在大多数程序里, 正则表达式都被置于两个正斜杠之间
vi, grep, awk ,sed 等等工具可以正则;ls、cp等不支持正则,要使用通配符
语系
LANG=C 时:01234...A B C D...Z a b c d...z
LANG=zh_TW 时:01234...a A b B c C d D...z Z
特殊符号
常用的:
[:alnum]代表所有的大小写英文字符和数字 0-9 A—Z a-z
例子:[root@localhost ~]# grep -n '[[:alnum:]]' a.txt //查找a.txt文档中的大小写英文字符和数字
[:alpha:]代表任意英文大小写字符 A-Za-z
例子:[root@localhost ~]# grep -n '[[:alpha:]]' a.txt //查找a.txt文档中的英文(无论大小写)
[:lower:]代表小写字符 a-z
例子:[root@localhost ~]# grep -n '[[:lower:]]' a.txt //查找a.txt文档中的英文(小写)
[:upper:]代表大写字符 A-Z
例子:[root@localhost ~]# grep -n '[[:upper:]]' a.txt //查找a.txt文档中的英文(大写)
[:digit:]代表数字 0-9
例子:[root@localhost ~]# grep -n '[[:digit:]]' a.txt //查找a.txt文档中的数字
其他特殊符号
普通的RE字符
-
^word 意义:匹配以字符串(word)为行首的行
///符号 ^ 在 [] 内时是取反的意思,在 [] 之外是行首的意思
例子:[root@localhost ~]# grep -n '^#' a.txt //匹配文档 a.txt 中以 # 开头的行
- word$ 意义:匹配以字符串(word)结尾的行
例子:[root@localhost ~]# grep -n '!$' a.txt //匹配文档 a.txt 中以 ! 结尾的行
- . 意义:匹配一定有的任意一个字符
例子:[root@localhost ~]# grep -n 'e.e' a.txt //匹配文档 a.txt 中含有的(e?e)字符串的行;不能是(ee)
- \ 转义符 意义:去除符号的特殊意义
例子:[root@localhost ~]# grep -n '\.' a.txt //匹配文档 a.txt 中含有的 . 字符串的行
- * 意义:重复匹配
零到无穷个前面的字符
例子:[root@localhost ~]# grep -n 'ess*' a.txt //匹配文档 a.txt 中含有(es)(ess)(esss)等的字符串的行
- [list] 意义:匹配在括号内的单个字符;中括号里面的特殊字符都失去特殊意义
例子:[root@localhost ~]# grep -n 'g[adf]l' a.txt //匹配文档 a.txt 中含有(gal)(gdl)(gfl)等的字符串的行
7.[^list] 意义:匹配括号内不含的单个字符
8.\{n,m\} 意义:连续匹配n到m个前一个RE字符
例子:[root@localhost ~]# grep -n 'go\{2,3\}g' a.txt //匹配文档a.txt 中含有的(goog)(gooog)
[root@localhost ~]# grep -n 'go\{,3\}g' a.txt //最多匹配3个
[root@localhost ~]# grep -n 'go\{2,\}g' a.txt //最少匹配2个
. 代表一个任意字符
* 代表重复零到多个在 其前面的一个字符
.* 代表零个或多个任意字符
例子:
1.ls -l a* #ls没有正则,这是通配符 ;匹配a后面有0或多个任意字符的文件
2.ls |grep -n '^a.*' #这是正则匹配; 匹配以a开头的后面带有0或任意的字符的文件
拓展正则
例子:([0-9] | [a-z]+)匹配0-9单个字符或者a-z多个小写英文字母。
拓展正则一般的grep不支持使用,要用到grep -E、egrep、sed、awk
-E, --extended-regexp PATTERN 是一个可扩展的正则表达式(缩写为 ERE)
-F, --fixed-strings PATTERN 是一组由断行符分隔的定长字符串。 (
grep的其他使用
-A n 匹配成功行的后n行同时输出
-B n 匹配成功行的前n行同时输出
-C n 匹配成功行的前后n行同时输出
-o 只显示匹配到的字符
-c 统计匹配到的行数
-l 只要文件名
-r 递归查找,就是在一个目录下查找
-n 显示匹配行及行号
。
关于-n 的解释
[root@localhost shell_learning_new]# grep -n root /etc/passwd
1:root:x:0:0:root:/root:/bin/bash
10:operator:x:11:0:operator:/root:/sbin/nologin
43:roo:x:1000:1000:root:/home/roo:/bin/bash
[root@localhost shell_learning_new]# grep -0n root /etc/passwd
1:root:x:0:0:root:/root:/bin/bash
--
10:operator:x:11:0:operator:/root:/sbin/nologin
--
43:roo:x:1000:1000:root:/home/roo:/bin/bash
作业
匹配一下手机号
137***
138***
152***
158***
159***
177***
172***
179***
180***
181***
182***
183***
185***
131***
132***
136***
156***
150***
199***
186***
187***
189***
匹配邮箱
vim telephone_number.txt
137999973807 137jahidhajgjdb 137938494888 13746a156514 13702378849 137026;oaydhd
138akdgouvdh ladlifIOLBFJB 13702398888
152kajdslafald 152kaj555gdd 15206156865568
158244646516136
159354613333
177464655556s
172564645555aas
179lalhfd45555
180s.ufhpo3535
181466466556
1825498465465
183576516765175
185546541315
131165461554
1324674616565
13615646565a
156f;osj;ajldj46556
150564651655
199435411613546
186465641656465
18754532132
189564651321
grep -no "^137[:digit:]{8}" telephone_number.txt //匹配到137开头的任意的11位电话号码
grep -o "1 (3[1-9] | 5[02689] | 7[279] | 8[0-9]) [0-9]{8}" telephone_number.txt
//13和15、17、18开头的全部匹配
grep -n "[[:alnum:]]+@(163|123|qq).com"
//匹配数字和字母开头的所有163和123的邮箱
正则的最高级部分:贪婪|非贪婪(扩展)
贪婪 就是尽可能的多匹配
非贪婪 就是尽可能的少匹配,只需要在一些表示量词(就是次数)的后面加上 ?, 比如: .*?
+?
grep 和egrep默认都是贪婪模式,不支持非贪婪模式
要想实现非贪婪需要使用 -P 参数(并且egrep不支持-P,因为egrep就是grep -E啦),这会使用 Perl 语言环境的正则
Perl 语言中:
\w 表示任意 一个 大小写字母 [a-zA-Z] 、下划线 _ 和数字 [0-9]
\d 表示任意 一个 数字 [0-9]
当然这些规则适用于大部分的 编程语言,比如 python java javascript go php 等。
root@localhost shell_learning_new]# echo 'gifubaissssssssssb' |grep 'g.*b'
gifubaissssssssssb
[root@localhost shell_learning_new]# echo 'gifubaissssssssssb' |grep -E 'g.*b'
gifubaissssssssssb
[root@localhost shell_learning_new]# echo 'gifubaissssssssssb' |egrep -o 'g.*b'
gifubaissssssssssb
[root@localhost shell_learning_new]# echo 'gifubaissssssssssb' |grep -Po 'g.*?b'
gifub
[root@localhost shell_learning_new]# echo 'gifubaissssssssssb' |egrep -P 's.*?b'
grep: 指定了互相冲突的比较程序
..........................................................
[root@localhost shell_learning_new]# echo "abcdcec" |grep -Po 'a[a-z]+c'
abcdcec
[root@localhost shell_learning_new]# echo "abcdcec" |grep -Po 'a[a-z]+?c'
abc
[root@localhost shell_learning_new]# echo "abccec" |grep -Po "a\w+?c"
abc
[root@localhost shell_learning_new]# echo "abccec" |grep -Po "a\w+c"
abccec