正则表达式

正则表达式笔记

本章是学习shell的基础,本章学的越好,shell也就会学的越好。

在计算机科学中,正则表达式的含义是:它使用单个字符串来描述或匹配一系列符合某个句法规则的字符串。在许多文本编辑器或工具里,正则表达式通常用来检索和替换那些符合某个模式的文本内容。对系统管理员来说,正则表达式贯穿我们的日常运维工作当中,无论是查找某个文档,还是查询某个日志文件并分析其内容,都会用到正则表达式。

其实正则表达式只是一种思想、一种表示方法。只要工具支持这种方法,这个工具就可以处理正则表达式的字符串。常用的正则表达式有grep、sed、awk,它们都是针对文本的行来操作的。

11.1 grep/egrep工具的使用

grep命令的格式为:

grep [-cinvABC] ‘word’ filename,其常用选项表示如下:

-c:表示打印符合要求的行数

-i:表示忽略大小写

-n:表示输出符合要求的行及其行号

-v:表示打印不符合要求的行

-A:后跟一个数字(有无空格均可),如-A2表示打印符合要求的行以及下面两行

-B:后跟一个数字,如-B2表示打印符合要求的行以及上面两行

-C:后跟一个数字,如-C2表示打印符合要求的行以及上下各两行

实例1

命令:

grep -A2 'halt' /etc/passwd

解释:

打印包含halt的行以及这行下面的两行

注:在CentOS 7中,grep默认帮我们把匹配到的字符串标注了红色。用which命令查看grep,可以看到grep其实就是grep --color=auto,这个选项就是颜色表示。

实例2

命令:

grep -B2 'halt' /etc/passwd

解释:

打印包含halt的行以及这行上面的两行

实例3

命令:

grep -C2 'halt' /etc/passwd

解释:

打印包含halt的行以及这行的上下两行

11.1.1过滤出带有某个关键词的行,并输出行号

实例1

命令:

grep -n 'root' /etc/passwd

解释:

过滤出带有root的行,并输出行号

注:前面的数字显示为绿色,表示行号

11.1.2过滤出不带有某个关键词的行,并输出行号

实例1

命令:

grep -nv 'nologin' /etc/passwd

解释:

过滤出不带有nologin的行,并输出行号

11.1.3过滤出所有包含数字的行

实例1

命令:

grep '[0-9]' /etc/passwd

解释:

过滤出所有包含数字的行

注:只要有一个数字就算匹配到了

11.1.4过滤出所有不包含数字的行

实例1

命令:

grep -v '[0-9]' /etc/inittab

解释:

过滤出所有不包含数字的行

注:只要有一个数字就不显示

11.1.5过滤掉所有以#开头的行

实例1

命令:

grep -v '^#' /etc/sos.conf

解释:

过滤掉所有以#开头的行

注:这里面是含有空行的

11.1.6过滤掉所有空行和以#开头的行

实例1

命令:

grep -v '^#' /etc/passwd | grep -v '^$'

解释:

过滤掉所有空行和以#开头的行

注:在正则表达式中,^表示行的开始,$表示行的结尾,那么空行可以表示为^$。

实例2

命令:

grep '^[^a-zA-Z]' test.txt

解释:

以非字母开头

实例3

命令:

grep '[^a-zA-Z]' test.txt

解释:

过滤出带有非字母项的行

注:[]的作用,如果是数字就用[0-9]这样的形式(如果是[15],表示只含有1或者5),如果要过滤数字以及大小写字母,则要写成类似[0-9a-zA-Z]的形式。另外,^在中括号以外表示以中括号里面的东西开头;^在中括号以内表示除中括号里面的东西以外。

11.1.7 过滤出任意一个字符和重复字符

实例1

.表示任意一个字符

命令:

grep 'r.o' /etc/passwd

解释:

过滤出r和o之间有任意一个字符的行

实例2

*表示零个或多个*前面的字符

命令:

grep 'ooo*' /etc/passwd

解释:

过滤出至少带有2个o的行

实例3

.*表示零个或多个任意字符,空行也包括在内,它会把文件中的所有行都匹配到

命令:

grep '.*' /etc/passwd

解释:

过滤出文件中的所有行

实例4

命令:

grep '.*' /etc/passwd | wc -l

解释:

文件总共的行数,包括空行

11.1.8 指定要过滤出的字符出现次数

{}内部为数字,表示前面的字符要重复的次数。需要强调的是,{}左右都需要加上转义字符\。另外,{}还可以表示一个范围,具体格式为{n1,n2},其中n1<n2,表示重复n1到n2次前面的字符。n2可以为空,此时表示大于等于n1次。

实例1

命令:

# grep 'o\{2\}' /etc/passwd

解释:

过滤出o重复2次的行

实例2

命令:

grep 'o\{2,3\}' /etc/passwd

解释:

过滤出o重复2到3次的行

实例3

命令:

grep 'o\{2,\}' /etc/passwd

解释:

过滤出o重复2次以上的行

11.1.9 egrep的用法

过滤出一个或多个指定的字符

实例1

命令:

egrep 'o+' test.txt

egrep 'oo+' test.txt

egrep 'ooo+' test.txt

解释:

过滤出至少有1个o,2个o,3个o的行

注:egrep使用的+,表示匹配1个或多个+前面的字符,但是+是不支持被grep直接使用的。同时,{}也可以被egrep直接使用而不用加转义字符\。

实例2

命令:

egrep 'o{2}' /etc/passwd

grep 'o\{2\}' /etc/passwd

grep -E 'o{2}' /etc/passwd

解释:

过滤出o被重复2次的行

11.1.10 过滤出零个或一个指定的字符

实例1

egrep中的?表示重复0个或1个前面的字符

命令:

egrep 'o?' test.txt

解释:

过滤出不带o或者带有1个o的行

实例2

命令:

egrep 'ooo?' test.txt

解释:

过滤出带2个o或者3个o的行

11.1.11 过滤出字符串1或者字符串2

实例1

命令:

egrep 'aaa|111|ooo' test.txt

解释:

过滤出带有3个a或者3个1或者3个o的行

11.1.12 egrep中()的应用

实例1

命令:

egrep 'r(oo|at)o' test.txt

解释:

()表示一个整体,会把包含rooo或者rato的行过滤出来

实例2

命令:

egrep '(oo)+' test.txt

解释:

过滤出包含1个或者多个oo的行

11.2sed工具的使用

grep只能实现查找功能,而不能把查找的内容替换。vim可以查找和替换,但只限于在文本内部操作,而不能输出到屏幕上。sed和awk都是流式编辑器,是针对文档的行来操作的。

11.2.1   打印某行

sed命令的形式为:sed –n ‘n’p filename,单引号内的n是一个数字,表示第几行。-n的作用是只显示我们要打印的行,无关紧要的内容不显示,不加-n是打印所有行。

实例1

命令:

sed -n '2'p test.txt

解释:

打印第2行

实例2

命令:

sed -n '1,$'p test.txt

解释:

打印所有行

实例3

命令:

sed -n '2,3'p test.txt

解释:

打印2-3行的内容

11.2.2   打印包含某个字符串的行

实例1

命令:

sed -n '/root/'p test.txt

解释:

打印包含root的行

实例2

在grep中适用的特殊字符(如^$.*)同样也能在sed中使用

命令:

sed -n '/^1/'p test.txt

解释:

打印以1开头的字符串

实例3

命令:

sed -n '/in$/'p test.txt

解释:

打印以in结尾的行

实例4

命令:

sed -n '/r..o/'p test.txt

解释:

打印r和o之间有任意两个字符的行

实例5

命令:

sed -n '/ooo*/'p test.txt

解释:

打印至少含有2个o的行

实例6

sed命令加-e选项可以实现多个行为。

命令:

sed -e '1'p -e '/111/'p -n test.txt

解释:

先打印第1行再打印含有111的行

11.2.3   删除某些行

实例1

命令:

sed '1'd test.txt

解释:

删除第1行

实例2

命令:

sed '1,3'd test.txt

解释:

删除1-3行

实例3

命令:

sed '/oot/'d test.txt

解释:

删除带oot的行

注:d表示删除的动作,它不仅可以删除指定的单行和多行,还可以删除匹配某个字符的行,还可以删除从某一行开始到文档最后一行的所有行。不过,这个操作仅仅是在显示器屏幕上并不显示这些行而已,文档还好好的,并未对文档做真实的编辑。

11.2.4   替换字符或者字符串

参数s是替换动作,参数g是本行全局替换,如果不加g则只是替换本行出现的第1个

实例1

命令:

sed '1,2s/ot/to/g' test.txt

解释:

1,2行的ot全局替换成to

实例2

除了可以用/做分隔符,也可以用#和@。

命令:

sed 's#ot#to#g' test.txt

sed 's@ot@to@g' test.txt

解释:

ot全局替换成to

实例3

命令:

sed 's/[0-9]//g' test.txt

解释:

删除所有的数字

注:[0-9]表示任意的数字,这里也可以写成[a-zA-Z]或者[0-9a-zA-Z]

实例4

命令:

sed 's/[a-zA-Z]//g' test.txt

解释:

删除字母

11.2.5   调换两个字符串的位置

实例1

命令:

sed 's/\(rot\)\(.*\)\(bash\)\3\2\1//' test.txt

解释:

调换rot和bash的位置

注:()在sed中式特殊符号,必须在前面加转义字符\,替换是写成类似\1、\2、\3的形式,()是把想要替换的字符打包成一个整体。

实例2

命令:

sed -r 's/(rot)(.*)(bash)/\3\2\1/' test.txt

解释:

加-r选项后()就可以不再使用转义字符表达式也更加清洗了。

实例3

命令:

sed 's/^.*$/123&/' test.txt

解释:

文件所有行开头加上123

实例4

命令:

sed 's/$/123&/' test.txt

解释:

结尾加上123

11.2.6   直接修改文件的内容(修改前先备份)

加-i选项,会对文档进行真实的修改

实例1

命令:

sed -i 's/ot/to/g' test.txt

解释:

真实修改文件的内容

11.3 awk工具的使用

11.3  awk工具的使用

awk也是流式编辑器,针对文档中的行来操作,一行一行地执行。

11.3.1   截取文档中的某个段

实例1

-F选项的作用是指定分隔符,如果不加-F选项,则以空格或者tab为分隔符。print为打印的动作,用来打印某个字段。$1为第一个字段,$2为第二个字段,依此类推。但$0比较特殊,它表示整行。

命令:

head -n2 test.txt | awk -F ':' '{print $1}'

解释:

用:做分隔符,打印test.txt前2行的第1段字符

实例2

命令:

head -n2 test.txt | awk -F ':' '{print $0}'

解释:

用:做分隔符,打印test.txt的前2行

注意awk的格式,-F后面紧跟单引号,单引号里面为分隔符。print动作要用{}括起来,否则会报错。

实例3

print可以打印自定义内容,但是自定义的内容要用“”括起来。

命令:

head -n2 test.txt | awk -F ':' '{print $1"#"$2"#"$3"#"$4}'

解释:

用:做分隔符,打印test.txt的前2行中第1,2,3,4部分,并且用#分开

11.3.2   匹配字符或者字符串

实例1

命令:

awk '/oo/' test.txt

解释:

打印test.txt中匹配oo的行

实例2

awk可以让某个段去匹配,~就是匹配的意思

命令:

awk -F ':' '$1 ~ /oo/' test.txt

实例:

用:做分隔符,打印第1段匹配oo的所有行

实例3

awk可以进行多次匹配

命令:

awk -F ':' '/root/ {print $1,$3} /test/ {print $1,$3}' test.txt

解释:

用:做分隔符,先匹配root再匹配test

11.3.3   条件操作符

awk可以用逻辑符号进行判断,判断符号有==(精确匹配)、>、>=、<、<=、!=。在和数字做比较时,数字加双引号表示字符,不加双引号表示数字。

实例1

命令:

awk –F ‘:’ ‘$3 == “0”’ /etc/passwd

解释:

/etc/passwd文件中,以冒号为分隔符,第3部分等于字符0

实例2

命令:

awk –F ‘:’ ‘$3 > 500’ /etc/passwd

解释:

把/etc/passwd中用户uid大于500的行打印出来

实例3

!=表示不匹配

命令:

awk –F ‘:’ ‘$7 != “sbin/nologin”’ /etc/passwd

解释:

把/etc/passwd中以冒号为分隔符第7部分不匹配/sbin/nologin的行打印出类

实例4  

&&的用法

命令:

awk -F ':' '$3>"5"&&$3<"7"' /etc/passwd

解释:

把/etc/passwd中以冒号为分隔符分开的第3部分大于5小于7的部分打印出来

实例5

||的用法

命令:

awk -F ':' '$3>1000 || $7=="/bin/bash"' /etc/passwd

解释:

把/etc/passwd中以冒号为分隔符分开的第3部分大于1000或者第7部分等于/bin/bash的行打印出来

11.3.4   awk的内置变量

awk常用的变量有OFS、NF、NR。

实例1

OFS的用法

命令:

head -5 /etc/passwd | awk -F ':' '{OFS="#"} {print $1,$3,$4}'

解释:

/etc/passwd的前5行中,以冒号为分隔符,打印第1,3,4部分,并以#分开这3部分

实例2

OFS的高级用法

命令:

awk -F ':' '{OFS="#"} {if ($3>1000) {print $1,$2,$3,$4}}' /etc/passwd

解释:

在/etc/passwd中,打印第1,2,3,4部分,且第3部分大于1000,并以#分开这4部分

实例3

变量NF的具体用法(NF表示分隔符分隔后一共有多少段)

命令:

head -n3 /etc/passwd | awk -F ':' '{print NF}'

解释:

在/etc/passwd中,以冒号分割后一共有多少段

实例4

$NF表示最后一段的值

命令:

head -n3 /etc/passwd | awk -F ':' '{print $NF}'

解释:

在/etc/passwd中,以冒号分割后打印最后一个字段

实例5

变量NR的用法(NR表示行号)

命令:

awk 'NR>10' test.txt

用法:

打印行数大于10的所有行

实例6

NR和配合段一起使用

命令:

awk -F ':' 'NR<20 && $1 ~ /root/' /etc/passwd

解释:

在/etc/passwd中以冒号为分隔符,打印所有行数小于20且第1部分匹配root的行

11.3.5   awk中的数学运算

实例1

awk可以更改段值,就是把目标段改为自己设定的东西

命令:

head -n3 /etc/passwd | awk -F ':' '$1="root"'

解释:

在/etc/passwd的前3行中,以冒号为分隔符,将第1段改为root

实例2

awk可以对各个段的值进行数学运算

命令:

head -n2 /etc/passwd | awk -F ':' '{$7=$3+$4;print $0}'

解释:

在/etc/passwd的前2行中,以冒号为分隔符,将第7段改为第3段和第4段的和

实例3

awk可以计算某个段的总和

命令:

awk -F ':' '{(tot=tot+$3)}; END {print tot}' /etc/passwd

解释:

用:作为分隔符,把整个文档的第3个字段相加,求和

实例4

命令:

awk -F ':' '{if ($1=="root") {print $0}}' /etc/passwd

解释:

用:作为分隔符,打印第1字段等于root的行

总结:上面这些仅仅是正则表达式中最基本的内容,sed和awk并没有深入讲解,但足以满足日常工作需要。碰到复杂的,再研究便是。

 

 

友情链接:阿铭Linux

转载于:https://my.oschina.net/u/3744518/blog/1592309

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值