Re-正则表达式, 以及grep使用
目录
简介
正则表达式(RE),是一种字符模式,用于在查找过程中匹配执指定的字符。
在大多数程序里,正则表达式都被置于两个正斜杠之间;例如/I[oO]ve/就是由正斜杠界定的正则表达式, 它将匹配被查找的行中任何位置出现的相同模式。在正则表达式中,元字符是最重要的概念。
用在
sed:文本处理
awk:截取,过滤文本
grep:截取,过滤文本
大小写严格区分
函数格式
^开头
$结尾
+前面的对象出现一次或者多次
.是任意多个字符
- 匹配数字 1+$ 123 456 #开头和中间只能有数字
- 匹配mail [a-z0-9_]+@[a-z0-9]+.[a-z]+ yangsheng1123@126.com .是任意多个字符
- 匹配IP [1-9]{1,3}.[[:digit:]]{1,3}.[[:digit:]]{1,3}.[[:digit:]]{1,3}
元字符
跟shell中大部分不一样
元字符是一类字符,他们搭配的都不是字面本身的含义
shell中的元字符(也成通配符),由shell来解析
正则表达式元字符 由各种执行匹配模式的程序来解析,比如vi 、grep、sed、awk、python
shell:* 解析为任意多个字符
*表示前面的字符出现零次或多次
//元字符--------功能------------------实例
^ 行首定位符 ^love
$ 行末尾位定位符 love$
. 匹配单个字符 l..e
* 匹配前导符0到多次 ab*love //这里匹配的是b
.* 任意多个字符
[] 匹配指定范围内的一个字符 [IL]ove
[-] 匹配指定范围内的一个字符 [a-z0-9]ove
[^] 匹配不在执行组内(都有)额字符 [^a-z0-9]ove
\ 用来转义元字符 love\. .将失去原有的作用。实现真实的love.
\< 词首定位符 \<love
\> 词尾定位符 love\>
\(...\) 匹配稍后使用的字符的标签 :% s/192.168.0.1/192.168.0.2/ 传统查找
:% s/\(192.168.0.\)1/\15/ 替换1处
:% s/\(192.\)\(16.\)\(130.\)1/\1\2\35/ 替换两处
:3,9 s/\(.*\)/#\1/ #3到9行 `.*`是整行 ,在前面加个#注释掉
x\{m\} 字符x重复出现m次 o\{5\}
x\{m,\} 字符x重复出现m次以上 o\{5,\}
x\{m,n\} 字符x重复出现m到n次 o\{5,10\}
//以上三种通过 grep执行加\或者通过egrep直接执行
//用egrep执行 或者转义字符\+ ...来执行
//++++++++++++++++++++++++++++++++++++++扩展正则表达式元字符
+ 匹配一个或则多个前导字符 [a-z]+ove
? 匹配零个或者一个前导字符 lo?ve
a|b 匹配a或者b love|hate
() 组字符相当于字符组 loveable|rs love(able|rs)ov+(ov)+
(..)(..)\1\2 标签匹配字符 (love)able\1er
x{m} 字符x重复m次 o{5}
x{m,} 字符x至少重复m次 o{5,}
x{m,n} 字符x重复m到n次 o{5,10}
//++++++++++++++posix字符类++++++++++++++++++++++++
表达式 功能 示例
[:alnum:] 字母与数字字符 [[:alnum:]]+
[:alpha:] 字母字符(包括大小写字母) [[:alpha:]]{4}
[:blank:] 空格与制表符 [[:blank:]]*
[:digit:] 字母与数字字符 [[:digit:]]?
[:lower:] 小写字母 [[:lower:]]{5,}
[:upper:] 大写字母 [[:upper:]]+
[:punct:] 标点符号 [[:punct:]]
[:space:] 包括换行符,回车等在内的所有空白内容 [[:space:]]+
实例
shell1.sh
grep 'b*love' /etc/local/passwd
vi 中执行:
%s/192.168.0.1/192.168.0.2/ 替换前者到后者
%s/(192.168.0.)1/\12/ 替换前者到后者,\1转义字符,代替前面的(192.168.0.)
%s/\(192.168.0.\)1/\12/ 替换前者到后者,\1转义字符,代替前面的\(192.168.0.\),括号前后增加转义符
#方便查看可以这样写
# %s ###
# %s #(192.168.0).1#\1.2# 或者
# %s #\(192.168.0.\)1#\12#
# %s #\(192.\)\(168.\)\(0.\)1#\1\2\32#
shell2.sh 元字符总结
#!/user/bin/bash
love* 0-n
love? 0-1
love+ 1-m
love{2} 2
#以上都是作用于字符e
#匹配一个或则多个前导字符
lo(ve)*
lo(ve)?
lo(ve)+
lo(ve){2}
#以上都是作用于字符组ve
/.*/ #整行
/^$/ #回车行
/^[A-Z]..$/ #三字符,首字符大写字母
/^[A-Z][a-z]*3[0-5]/ #在[A-Z]开头,[a-z]*,产生零到多个小写字母,3字符,[0-5]数字
/[a-z]*\./ #[a-z]*,产生零到多个小写字母 再加一个点.
/^ *[A-Z][a-z][a-z]$/#^ *,产生零到多个空格 [A-Z][a-z]产生两个字符,范围分别为[A-Z][a-z],[a-z]$再以[a-z]中一个字符结尾
/^[A-Za-z]*[^,][A-Za-z]*$/
/\<fourth\>/ #找单词
/\<f.*th\>/ #固定开头,固定结尾
/5{2}2{3}\./ #5出现2此。2出现3此,在加上一个.
#空行
/^$/
/^[\t]*$/ #零到多个tab建开头
#注释行
/^#/
/^[\t]*#/ #零到多个tab建开头
$ s/\(sa\) and \(as\)/\2 and \1/ #sa 与as互换位置
\w 所有字母和数字,称之为字符 'l[a-z0-9A-z]*ve' 等价于'l\w*ve'
\W 所有字母和数字之外的字符 成为非字符 'l[^a-z0-9A-z]+' 等价于'l\W+'
\b 词边界 '\<love\>' 等价于 '\blove\b'
shell3.sh grep实战
grep: 在文件中全局查找指定的正则表达式,并打印所有包含该表达式的行 ^,$,.,*,[],[^],<>,(),{},| egrep: 扩展的egrep,支持更多的正则表达式元字符 或者 grep -E ? ,+, {},|,() fgrep: 固定grep(fixed grep),又是也被乘坐靠偶素匹配,它按字面解释所有的字符
格式命令 grep [选项] pattern filename filename
返回值
0:找到 1:没找到内容 2:没找到文件
选项
-i 忽略大小写 -l 只列出匹配行所在的文件名 -n 在每一行前面加上它在文件中的相对行号 可用 vim /etc/passwd +50执行后进行编辑 -c 显示成功匹配的行数 -s 禁止显示文件不存在或文件不可读的错误信息 -q 没有打印,静默 -v 反向查找,只显示不匹配的行 -R,-r 递归针对目录 --color 颜色 -o 只显示匹配的内容 -B print NUM lines of leading context 语境 前部-B2 -A print NUM lines of trailing context 语境 后部-B2 -C print NUM lines of output context 语境 输出的 一般通过以下命令进行查看
man find
然后输入/
可以看到:变成/
输入要查找的字符串
-q
按下回车
可以看到高亮出了-p字符串,如果这样的字符串有很多,我们要搜索下一个字符串,按下n下一条,按下N(shift+n)上一条
grep程序的输入可以来自标准输入或者管道,而不仅仅是文件,例如:
# grep 'tom' # ps aux |grep 'sshd' # ll |grep '^d' # grep 'alice' /etc/passwd /ect/group
egrep 'NM' datafile #datafile在找文件有NW的行 egrep 'nw' d* #以d开头的所有文件中在找文件有NW的行 egrep '^n' datafile #datafile在找文件有n开始的行 egrep '4$' datafile #datafile在找文件有4结尾的行 egrep TB savage datafuke #在savage和datafuke文件中找到TB egrep 'TB savage' datafuke #在datafuke中找到TB savage的行 egrep '5\..' datafuke #在datafuke中找到5.和任意字符(5.1之类的)的行 egrep '\.5' datafuke #在datafuke中找到.5的行 egrep '^[we]' datafuke #在datafuke中找到w或者e开头的行 egrep '[^0-9]' datafuke #在datafuke中找到非数字的行 egrep '[A-Z][A-Z] [A-Z]' datafuke #在datafuke中找到四个字符,分别是都是A到Z,A到Z,A到Z,空格,A到Z egrep 'ss*' datafuke #在datafuke中找到s及s*(0个或者多个s的行)的行,简写成s+ egrep '[a-z]{9}' datafuke #在datafuke中找到[a-z]且连续出现9次的行 egrep '\<north' datafuke #在datafuke中找到north词首的行 egrep '\<north\>' datafuke #在datafuke中找到north单词的行 egrep '\<[a-z].*n\>' datafuke #在datafuke中找到[a-z]开头,中间任意个字符,n结尾的行 egrep '^n\w*\W' datafuke #在datafuke中找到n开头,中间任意个字符,非字符结尾 egrep '\bnorth\b' datafuke #在datafuke中找到north单词的行 egrep 'nw|EA' datafuke #在datafuke中找到有nw或者EA单词的行 egrep '3+' datafuke #在datafuke中找到有1个或者多个3的行 egrep '2\.?[0-9]' datafuke #在datafuke中找到有z,有零个或者一个. ,再有一个数字的行 egrep '(no)+' datafuke #在datafuke中找到有1个或者多个no的行 egrep 'S(n|o)' datafuke #在datafuke中找到有sn或者so的行 egrep 'Sn|o' datafuke #在datafuke中找到有sn或者o的行 egrep -o '([0-9]{1,3}\.){3}[0-9]{1,3}' datafuke #在datafuke中找到有ip的行 grep --help |grep '\-R' #这里需要加反斜线\,要不然会当成个grep的选项 grep --help |egrep -A5 '\-R' #这里需要没有用到执行\
- 0-9 [return]