Linux系统Shell脚本-----------正则表达式 、grep、 sed

一、正则表达式

1.前言


正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。在Linux中也就是代表我们定义的模式模板,Linux工具可以用它来过滤文本。

Linux的工具(如sed编辑器或者gawk程序)能够在处理数据时使用正则表达式对数据进行模式匹配,如果数据符合匹配的要求,那么就会进入下一步处理;如果数据不符合匹配的要求,就会被过滤掉。

通配符功能是用来处理文件名,而正则表达式是处理文本内容中字符。

正则表达式被很多程序和开发语言所广泛支持:vim, less,grep,sed,awk, nginx,mysql 等

主要用来匹配字符串(命令结果,文本内容)

2.正则表达式介绍

1、正则表达式---通常用于判断语句中,用来检查某一字符串是否满足某一格式

2、正则表达式是由普通字符与元字符组成

3、普通字符包括大小写字母、数字、标点符号及一些其他符号

4、元字符是指在正则表达式中具有特殊意义的专用字符,可以用来规定其前导字符(即位于元字符前面的字符或表达式)在目标对象中的出现模式

3.正则表达式类型

  • 基本正则表达式  (BRE :basic regular expression)

  • 扩展正则表达式  (ERE:xtended regular expression)

  • 编程语言支持的高级正则表达式

man 7 regex
可以使用 man手册帮助

基本正则表达式 、 扩展正则表达式 的区别是不用写   \ (意思是转义)

grep sed  默认使用基础正则表达式
grep -E、 sed -r、   egrep、  awk  扩展正则表达式

4.正则表达式特点

元字符:预定义好的具有特殊含义的符号,这些符号能够进行通配

写正则表达式不难

可读性非常的差

二、基本正则表达式

1.元字符(字符匹配)

  • 普通字符包括大小写字母、数字、标点符号及一些其他符号。
  • 元字符是指在正则表达式中具有特殊意义的专用字符,可以用来规定其前导字符( 即位于元字符前面的字符)在目标对象中的出现模式。

元字符:

注册用户   数字字母组成        20字符

\ 转义字符,可以把一些特殊的符号转换成普通的符号字符,还可以把一些普通字符转换成特殊功能,例:\!、\n、\$等
^ 表示匹配字符串开始的位置,匹配行首 例如: ^a    ^the    ^#   ^[a-z]
$ 表示匹配字符串结束的位置,例: word$
^$ 匹配空行
. 匹配除\n之外的任意的一个字符,表示任意单个字符 例: go.d、 g…d
* 匹配前面子表达式0次或者多次,例: goo*d、go.*d
.*

前面字符可以出现无数次,一到正无穷次,

但出现0次,不能匹配;最少出现一次

[ ] 匹配[ ]中包含的任一字符,单个字符
[^]  匹配指定范围外的任意单个字符,示例:[^zhou]   [^a.z]    [a.z]
[^] 匹配指定范围外的任意单个字符,示例:[^zhou] [^a.z] [a.z]
[:alnum:] 字母和数字
[:alpha:] 代表任何英文大小写字符,亦即 A-Z, a-z
[:lower:] 小写字母,示例:[[:lower:]],相当于[a-z]
[:upper:] 大写字母
[:blank:] 空白字符(空格和制表符)
[:space:] 包括空格、制表符 (水平和垂直)、换行符、回车符等各种类型的空白,比[:blank:]包含的范围广
[:cntrl:] 不可打印的控制字符(退格、删除、警铃...)
[:digit:] 十进制数字
[:xdigit:]十六进制数字
[:graph:] 可打印的非空白字符
[:print:] 可打印字符
[:punct:] 标点符号
\w #匹配单词构成部分,等价于[_[:alnum:]]
\W #匹配非单词构成部分,等价于[^_[:alnum:]]
\S     #匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
\s     #匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。注意Unicode 正则表达式会匹配全角空格符

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第1张图片


.  在方框中只代表  .  

.  不在方框中代表单个字符

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第2张图片

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第3张图片

[^]    匹配指定范围外的任意单个字符,示例: [^a.z]        [a.z]

标准格式   需要加  '   '   或者 "   "

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第4张图片

abc   匹配字符串”abc",普通字符的匹配

[abcde ...]   匹配中括号内的任意单个字符
a[xyz]b    axb、ayb、azb,不能匹配aab amb

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第5张图片

\n :匹配换行符
\t :匹配制表符
\w :匹配单词字符 [a-zA-Z0-9_]
\W :匹配非单词字符 [^a-zA-Z0-9_]
\s :匹配空白字符
\S :匹配非空白字符
\d :匹配数字
\D :匹配非数字
. 表示匹配任意单个字符

字符组:

普通中括号包围的字符组:表示某单个字符匹配中括号内的任一字符即匹配成功

x[abc]z:可以匹配包含”xaz” 、 "xbz"、"xcz"的字符串

取反表示法:中括号内开头使用^,表示只要不是中括号中的字符就匹配

x[^abc]z :可匹配包含"xdz"、“xez"等的字符串,但不能匹配包含"xaz”、“xbz”、“xcz”的字符串

范围表示法:

[a-z]:代表任一单个小写字母
[^a-z]:只要单个非小写字母的其它任一单个字符
[A-Z]:代表任一单个大写字母
[0-9]:代表任一单个数字

注:[0-59]   表示匹配0 、1、2、3、4、5、9 而不是0到59中间的数值

[a-z0-9A-Z]:代表任一字母或数字
[a-z0-9A-Z_]:代表任一字母、数字或下划线,即匹配单词字符 (word)
[A-z]或[a-Z]”: 建议不要使用这种横跨大小写字母的范围表达式,不同地方表达的含义不同,甚至有些按照字典顺序排序时,[a-d] 不是等价于abcd,而是等价于aBbCcDd。如果想要等价于abcd,应将locale环境设置为LC_ALL=C

特殊元字符在中括号中的匹配:
想要在中括号中匹配 ^  需将其放在中括号的非开头位置,如 [a^]

想要在中括号中匹配 -   需将其放在开头位置或结尾位置,如 [abc-] 、 [-abc] 

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第6张图片

2.表示次数

*           #匹配前面的字符任意次,包括0次,贪婪模式:尽可能长的匹配
.*          #任意长度的任意字符  不包括0次     
\?          #匹配其前面的字符出现0次或1次,即:可有可无
\+          #匹配其前面的字符出现最少1次,即:肯定有且 >=1 次
\{n\}       #匹配前面的字符n次
\{m,n\}     #匹配前面的字符至少m次,至多n次
\{,n\}      #匹配前面的字符至多n次,<=n
\{n,\}      #匹配前面的字符至少n次

  *   匹配前面子表达式出现0次或者多次

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第7张图片

.*       任意长度的任意字符  不包括0次     至少出现1次

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第8张图片

\?     匹配其前面的字符出现0次或1次,即:可有可无

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第9张图片

\+   匹配其前面的字符出现最少1次, 即:肯定有且 >=1 次

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第10张图片

\{n\}       匹配前面的字符n次

\{m,n\}    匹配前面的字符至少m次,至多n次

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第11张图片

\{n,\}     匹配前面的字符至少n次

\{,n\}     匹配前面的字符最多n次

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第12张图片

3.位置锚定

^ #行首锚定, 用于模式的最左侧
$ #行尾锚定,用于模式的最右侧
^PATTERN$ #用于模式匹配整行 (单独一行  只有root)
^$ #空行   
^[[:space:]]*$ #  空白行    tab   换行  回车


\< 或 \b        #词首锚定,用于单词模式的左侧(连续的数字,字母,下划线都算单词内部)
\> 或 \b        #词尾锚定,用于单词模式的右侧
\     #匹配整个单词

\root\

4.分组或其他

分组:( ) 将多个字符捆绑在一起,当作一个整体处理,如:(root)+

后向引用:分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量中,这些变量的命名

方式为: \1, \2, \3, ... 分组

\1 表示从左侧起第一个左括号以及与之匹配右括号之间的模式所匹配到的字符

或者
或者:\|

三、扩展正则表达式(表示字符相差不大)

grep -E

egrep 默认使用的 是扩展正则表达式

表示次数

*         匹配前面字符任意次
?        表示匹配前面的子表达式0或者1次
+        表示匹配前面的子表达式1次以上 (1次或多次)
{n}      匹配n次
{m,n}   至少m,至多n次
{,n}      匹配前面的字符至多n次,<=n,n可以为0
{n,}      匹配前面的字符至少n次,<=n,n可以为0

表示分组

( )

将括号里的内容看成一个整体
| 以或的方式匹配字符串
+ 表示匹配前面的子表达式1次以上 (1次或多次)
表示匹配前面的子表达式0或者1次
Linux系统Shell脚本-----------正则表达式 、grep、 sed_第13张图片
分组:() 将多个字符捆绑在一起,当作一个整体处理,如:\(root\)+
后向引用:\1, \2, ...   
 | 或者  
a|b         #a或b
C|cat      #C或cat
(C|c)at    #Cat或cat

实验:

匹配 qq号    (一般qq号5到12位)

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第14张图片

匹配 手机号    (一般11位)

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第15张图片

匹配邮箱

四、grep

格式:  grep [选项]… 查找条件 目标文件              

grep 默认使用基础正则表达式

-m     #匹配#次后停止      匹配到 #行 停止   

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第16张图片

-v     显示不被pattern匹配到的行,即取反

-i     忽略字符大小写

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第17张图片

-n     显示匹配的行号

-c     统计匹配的行数 ,统计匹配到的行数

-o    仅显示匹配到的字符串

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第18张图片

-q      静默模式,不输出任何信息    写脚本用哦

面试题: -A   -B  -C  这三个选项

-A          #after, 后#行 

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第19张图片

-B        #before, 前#行

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第20张图片

-C         #context, 前后各#行

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第21张图片

-e     实现多个选项间的逻辑or关系     如:grep –e ‘cat ' -e ‘dog' file

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第22张图片

-w       匹配整个单词

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第23张图片

-E 使用ERE,相当于egrep   

-f   file 根据模式文件,处理两个文件相同内容 把第一个文件作为匹配条件   grep  -f   a    b
-r   递归目录,但不处理软链接     开始搜索目录
-R   递归目录,但处理软链接

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第24张图片

面试题:

统计当前主机的连接状态             ss -nta | grep -v '^State' |cut -d" " -f1|sort |uniq -c

统计当前连接主机数                 ss -nt |tr -s " "|cut -d " " -f5|cut -d ":" -f1 |sort|uniq -c           

五、sed

sed 即 Stream EDitor,和 vi 不同,sed是行编辑器

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第25张图片

Sed是从文件或管道中读取一行,处理一行,输出一行;再读取一行,再处理一行,再输出一行,直到最后一行。每当处理一行时,把当前处理的行存储在临时缓冲区中,称为模式空间(PatternSpace),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。一次处理一行的设计模式使得sed性能很高,sed在读取大文件时不会出现卡顿的现象。如果使用vi命令打开几十M上百M的文件,明显会出现有卡顿的现象,这是因为vi命令打开文件是一次性将文件加载到内存,然后再打开。Sed就避免了这种情况,一行一行的处理,打开速度非常快,执行速度也很快

1.sed概述

sed是一种流编辑器,流编辑器会在编辑器处理数据之前基于预先提供的一组规则来编辑数据流。
sed编辑器可以根据命令来处理数据流中的数据,这些命令要么从命令行中输入,要么存储在一个命令文本文件中。

2.sed的工作流程

sed 的工作流程主要包括读取、执行和显示三个过程∶

读取∶ sed 从输入流(文件、管道、标准输入)中读取一行内容并存储到临时的缓冲区中 (又称模式空间,pattern space)
执行:默认情况下,所有的sed 命令都在模式空间中顺序地执行,除非指定了行的地址, 否则sed 命令将会在所有的行上依次执行。
显示∶发送修改后的内容到输出流。在发送数据后, 模式空间将会被清空。在所有的文件内容都被处理完成之前,上述过程将重复执行,直至所有内容被处理完。

在所有的文件内容都被处理完成之前,上述过程将重复执行, 直至所有内容被处理完
注意∶ 默认情况下所有的sed命令都是在模式空间内执行的,因此输入的文件并不会发生任何变化,除非是用重定向存储输出。

3.sed与vi的区别

vi命令打开文件是一次性将文件加载到内存,然后再打开。

Sed就避免了这种情况,一行一行的处理,打开速度非常快,执行速度也很快。

4.基本用法

sed [option]... 'script;script;...' [input  file...]
     选项         自身脚本语法         支持标准输入管道

5.sed脚本语法及命令

单引号中间需要写脚本;脚本格式如下:

'地址+命令' 组成     

地址:

1. 不给地址:对全文进行处理(比如行号)
2. 单地址:
   #:指定的行,$:最后一行
   /pattern/:被此处模式所能够匹配到的每一行,正则表达式
3. 地址范围:
   #,#     #从#行到第#行,3,6 从第3行到第6行
   #,+#   #从#行到+#行,3,+4 表示从3行到第7行
   /pat1/,/pat2/    第一个正则表达式和第二个正则表达式之间的行
   #,/pat/  从#号行为开始找到 pat为止 
   /pat/,#  找到#号个pat为止
4. 步进:~
     1~2 奇数行
     2~2 偶数行
sed -n 'n;p' testfile1		#打印偶数行
ed -n '2,${n;p}' testfile1

 不给地址:对全文进行处理(比如行号)

命令

p 打印当前模式空间内容,追加到默认输出之后
Ip 忽略大小写输出
d 删除模式空间匹配的行,并立即启用下一轮循环
a [\]text 在指定行后面追加文本,支持使用\n实现多行追加
i [\]text 在行前面插入文本
c [\]text 替换行为单行或多行文本
w file 保存模式匹配的行至指定文件   seq 10 |sed -n '2wa.txt'
r file 读取指定文件的文本至模式空间中匹配到的行后    seq 10|sed '2r /etc/issue'
= 为模式空间中的行打印行号   sed '2=' /etc/passwd      sed -n -e '=;p' /etc/passwd
! 模式空间中匹配行取反处理seq 10 |sed -n '1~2!p'
q           结束或退出sed     seq 10 | sed '3q'

①sed脚本语法:地址+sed自己脚本命令,地址即范围例如全文或第一行,第一行至第三行等范围

②sed脚本命令:

p  打印当前模式空间内容  使用时关闭自动打印功能结合 -n 选项使用

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第26张图片

q       结束或退出sed   

d      删除模式空间匹配的行,并立即启用下一轮循环

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第27张图片

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第28张图片

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第29张图片

a   [\]text   在指定行后面追加文本,支持使用\n实现多行追加

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第30张图片

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第31张图片

i   [\]text   在行前面插入文本

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第32张图片

c  [\]text 替换行为单行或多行文本

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第33张图片

=   为模式空间中的行打印行号

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第34张图片

w      file(文件) 保存模式匹配的行至指定文件

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第35张图片

r       file 读取指定文件的文本至模式空间中匹配到的行后 

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第36张图片

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第37张图片

地址范围:

 不给地址:对全文进行处理(比如行号)

 #,#    #从#行到第#行

 /pat1/,/pat2/    第一个正则表达式和第二个正则表达式之间的行

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第38张图片

步进:~
     1~2 奇数行
     2~2 偶数行

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第39张图片

高级用法: 

sed -n 'n;p' testfile1        #打印偶数行
ed -n '2,${n;p}' testfile1

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第40张图片

面试题:

如何打印一段时间间的日志

有一段时间本机访问量过高,如何查看日志提取出访问量前十的信息:

1.使用提取命令 (cut、awk、sed) 提取出ip地址的那一列

2使用sort按数字排序,将相同的地址整合到一起
3使用uniq -c统计出数量
4.使用sort 数字数字倒序排序
5.最后用head 取前十

6.sed选项

常用选项:

-n 不输出模式空间内容到屏幕,即不自动打印
-e 多点编辑[root@www data]#sed -n -e '/^r/p'  -e'/^b/p' /etc/passwd
-f FILE 从指定文件中读取编辑脚本
-r, -E 使用扩展正则表达式
-i.bak 备份文件并原处编辑

-i.bak 备份文件并原处编辑

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第41张图片

-n 不输出模式空间内容到屏幕,即不自动打印,关闭自动打印

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第42张图片

7.sed查找替换使用

s/pattern/string/修饰符 查找替换,支持使用其它分隔符,可以是其它形式:s@@@,s###
替换修饰符:
g 行内全局替换
p 显示替换成功的行
w   /PATH/FILE 将替换成功的行保存至文件中
I,i   忽略大小写

格式:sed '/可使用正则表达式选择范围/' s/查找内容/替换内容/g

            g表示全文,固定格式的///可以用###等符号替换

注意:查找内容可使用正则表达式,替换内容不可使用正则表达式

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第43张图片

-i选项 备份selinux配置文件后缀加.bak  在config文件中找到SELINUX=enforcing修改为SELINUX=disabled,g表示所有搜索到的内容都替换。

分组替换:

只有扩展正则表达式才可以实现分组替换

分组后向引用

( )内的按顺序标为123 ,引用时\1调用第一个()的内容,\n表示调用第n个()的内容。

.*表示任意长度字符不管是什么字符

\1 表示从左侧起第一个左括号以及与之匹配右括号之间的模式所匹配到的字符

  1. -n选项关闭自动打印,-r  选项开启扩展正则表达式

  2. 's///'查找替换标准格式。三个()括起来的内容分别表示元素123,调用时改变调用顺序打印即可改变内容顺序

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第44张图片

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第45张图片

取ip地址

方法一:

ifconfig ens33 |sed -nr   's/.*inet (.*) netmask.*/\1/p'

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第46张图片
#查看ens33的网卡信息传给sed处理,-n选项关闭自动打印,-r选项开启扩展正则表达式
's///'查找替换标准格式,.*inet 表示以inet为止的前面所有字符 (.*) 括号表示使用反向引用
.*表示该处的任意字符 netmask.*表示以netmask开头后面的所有字符。\1表示反向引用第一个()的
内容,p表示打印出来。

方法二:

ifconfig ens33|sed -rn '2s/.*inet ([0-9.]+) .*/\1/p'

Linux系统Shell脚本-----------正则表达式 、grep、 sed_第47张图片

8.变量

使用sed查询是可以直接调用变量,注意必须用“ ”号或者俩个双引号,单引号不识别变量

下回分析

修改端口

修改网卡

变量

提取版本号

提取网卡名

提取0644

你可能感兴趣的:(正则表达式)