[toc]
正则表达式之grep,sed
一 grep
1.1 什么是正则
正则就是一串有规律的字符串
掌握好正则对于编写shell脚本有很大帮助
各种编程语言中都有正则,原理是一样的
本章将要学习grep/egrep、sed、awk
1.2 grep介绍
grep命令构成,在CentOS7中自带颜色
[root@xaviyunserver grep]# which grep
alias grep='grep --color=auto'
/usr/bin/grep
- [ ] grep [-cinvABC] 'word' filename
- [ ] -c 行数
- [ ] -i 不区分大小写
- [ ] -n 显示行号
- [ ] -v 取反,相反的显示
- [ ] -r 遍历所有子目录及孙目录
- [ ] -A 后面跟数字,过滤出符合要求的行以及下面n行
- [ ] -B 同上,过滤出符合要求的行以及上面n行
- [ ] -C 同上,同时过滤出符合要求的行以及上下各n行
举例:新建一个grep目录,将etc/passwd目录下的内容拷贝到grep目录下
[root@localhost ~]# mkdir grep
[root@localhost ~]# cd grep/
[root@localhost grep]# cp /etc/passwd . //建议此处改为cp /etc/passwd test.txt,防止误操作
[root@localhost grep]# ls
passwd
说明,gerp默认匹配到的字符串标注为红色,用which命令看一下,是带颜色自动显示的
1. grep -c 表示打印符合要求的行数
[root@localhost grep]# grep -c 'nologin' passwd
38
2. grep -n 表示输出符合要求的行及行号
3. grep -v 表示打印不符合要求的行
4. grep -r 遍历所有子目录
如果不加r则显示:
[root@localhost grep]# grep 'root' /etc/
grep: /etc/: 是一个目录
5. 通过grep遍历所有root文件并找到与passwd相关的
6.grep -A2 会把包含root的行以及这行下面的两行打印出来
7.grep -B2 会把包含root的行以及这行上面的两行打印出来
8. grep -C2 会把包含root的行以及这行上下各两行打印出来
grep/egrep示例
9. 过滤出带有某个关键词的行,并输出行号
- [ ] grep -n 'root' /etc/passwd
10. 过滤出不带某个关键词的行,并输出行号
- [ ] grep -nv 'nologin' /etc/passwd
11.过滤出所有包含数字的行
- [ ] grep '[0-9]' passwd
12.过滤所有不包含数字的行
- [ ] grep -v '[0-9]'/etc/inittab
- grep -vn 举例,把不含数字的行打印出来,vim编辑时输入:set nu 提示行号
13.过滤掉所有以#开头的行
- [ ] grep -v '^#' /etc/inittab 为了便于测试,需要将/etc/inittab拷贝出来到gerp目录下
[root@localhost grep]# cp /etc/inittab ./ //拷贝的测试目录grep下
编辑inittab文件,把带#号的两行修改了,方便测试 这在后续查找文件时,方便阅读
13.过滤掉所有的空行和以#开头的行
- [ ] grep -v '^#' inittab |grep -v '^$' 在正则表达式中, “^” 表示行的开始, “$” 表示行的结尾,那么空行则可以用 “^$” 表示。
[root@localhost grep]# grep -v '^#' 1.txt |grep -v '^$'
deda
deda
Deded
D
DdFFF1212
121324#
232
wq3
ewdsd
14. 过滤掉所有不包含数字的行
- [ ] grep '[^0-9]' inittab
15. 过滤所有开头是0-9的行
- [ ] grep '^[0-9]' inittab
[root@localhost grep]# grep -v '^[0-9]' 1.txt
deda
deda
###
Deded
D
$21212
[root@localhost grep]# grep -v '[^0-9]' 1.txt
232
121342
[root@localhost grep]# grep '[^0-9]' 1.txt
deda
deda
###
Deded
D
DdFFF1212
121324#
wq3
ewdsd
$21212
&32323
DED
eweq
16. 过滤出任意一个字符和重复字符
-
[ ] grep 'r.o' passwd //‘r.o’中.表示任意一个字符 为方便测试需要vim其中的passwd文件,并添加r&o等特殊字符
-
[ ] grep 'oo*' passwd passwd,表示零个或多个前面的字符,0~n个o
[root@localhost grep]# grep 'oo*' passwd|wc -l
46 //结果相同
[root@localhost grep]# grep 'o*o' passwd|wc -l
46
-
[ ] grep '.*' passwd passwd,.*表示零个或多个任意字符,空行也包含在内,这样就把passwd里面所有的行都匹配到。
-
[ ] grep 'o{2}' passwd passwd,这里{},其内部为数字,表示前面的字符要重复的次数,需要强调的是{}左右都要加上脱义字符,另外{}还可以表示一个范围,{1,3}表示重复1到3次前面的字符,{1,}表示大于1次重复前面字符
[root@localhost grep]# grep 'o\{2\}' 1.txt
dederoooooo
rooooooooooooooot:Z:SZXX:XD::X:SX:rooooot
- [ ] egrep 'o{2}' /etc/passwd 等同于上面的命令
== grep 'o\{2\}' passwd == grep -E 'o{2}' /etc/passwd
- [ ] egrep 'o+o'passwd,+表示匹配1个或者多个+前面的字符
[root@localhost grep]# grep 'o\+o' passwd |wc -l
6
[root@localhost grep]# egrep 'o+o' passwd |wc -l
6
19.egrep过滤出一个或者多个制定的字符
- [ ] egrep 'o?t' passwd,过滤出零个或者一个指定的字符
[root@localhost grep]# grep 'r.o' test.txt
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@localhost grep]# vim 1.txt
[root@localhost grep]# egrep 'o+' 1.txt
dederoooooo
rooooooooooooooot:Z:SZXX:XD::X:SX:rooooot
rot:s3we3e:e3e:sw4e
opertor:2323:323:DEX:WSsw:wewe
[root@localhost grep]# egrep 'oo+' 1.txt
dederoooooo
rooooooooooooooot:Z:SZXX:XD::X:SX:rooooot
[root@localhost grep]# egrep 'ooo+' 1.txt
dederoooooo
rooooooooooooooot:Z:SZXX:XD::X:SX:rooooot
- [ ] egrep 'root|nologin' passwd,|表示或者,可以有多个|
== grep -E
[root@localhost grep]# egrep 'root|nologin' passwd|wc -l
39
[root@localhost grep]# grep -E 'root|nologin' passwd|wc -l
39
20.用( )表示一个整体,例如(oo)+就表示1个 ‘oo’ 或者多个 ‘oo’
- [ ] egrep '(oo){2}' passwd
sed工具使用
- sed -n,选项表示只显示我们要打印的行,请看-n和没有-n的区别
[root@localhost ~]# mkdir sed
[root@localhost ~]# cd sed
[root@localhost sed]# cp ../grep/passwd test.txt
[root@localhost sed]# sed -n '/root/'p test.txt
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
- sed -r 这里-r和grep里面-E一样,还有加上了才能有效 支持+,*,.,|或者,与等
[root@localhost sed]# sed -n '/o+t/'p test.txt
[root@localhost sed]# sed -nr '/o+t/'p test.txt
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
setroubleshoot:x:991:986::/var/lib/setroubleshoot:/sbin/nologin
- sed打印某行
#sed -n '2'p test.txt //打印第二行
sed -n '1,$'p test.txt //打印所有行
sed -n '1,5'p test.txt //打印1~5行
[root@localhost sed]# sed -n '1,5'p test.txt
root:x:0:0:root:/root:/bin/bash
adsda:deda:deded:road:ded
sasdda:deda:&&DE:r&o:r<xo:
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
- sed -e 可以实现多个行为
[root@localhost sed]# sed -e '1'p -e '/root/'p -n test.txt
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@localhost sed]# sed -e '1'p -e '/bus/'p -n test.txt
root:x:0:0:root:/root:/bin/bash
systemd-bus-proxy:x:999:997:systemd Bus Proxy:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
- sed -i 删除某些行
sed -i '1,10'd test.txt //删除1到10行
[root@localhost sed]# wc -l test.txt
48 test.txt
[root@localhost sed]# sed -i '1,10'd test.txt
[root@localhost sed]# wc -l test.txt
38 test.txt
删除和user(字符串)相关的
[root@localhost sed]# sed -i '/user*/'d test.txt
[root@localhost sed]# wc -l test.txt
32 test.txt
- 替换字符或字符串,参数s表示替换的动作,g表示本行全局替换,如果不加g则只替换本行出现的一个,用法同vim
#sed ‘1,10s/sbin/sbbin/g’ test.txt 这里使用/作为分隔符,还可以是用其他特殊字符,#和&
- 替换扩展 #sed -r '1,10s/ro+/r/g' test.txt |head//要想+这类特殊符号生效必须加上-r,这里都是临时打印出来的结果,原有txt文档内容不变。
- 查找并替换
- 调换两个字符串的顺序
#sed -r 's/([^:]+):(.*):([^:]+)/\3:\2:\1/' // s是替换,^:非冒号字符串,.*非特殊符号的字符串,这里会遍历到随后一个冒号前。转义字符,替换成\3,\2,\1的形式
- 删除文档中所有的英文字母
[root@localhost sed]# head test.txt |sed 's/[a-zA-Z]//g'
::0:0::/://
::::
::&&:&:<:
::1:1::/://
::2:2::/://
::3:4:://://
::4:7::///://
::5:0::/://
::6:0::/://
::7:0::/://
- 在所有的行内容前面加上aaa:
- [ ] head test.txt |sed -r 's/(.*)/aaa:\1/' 这里\1或在&都可以表示字符串前面.