shell-——正则表达式

目录

正则表达式之

                元字符

                表示次数

                位置锚定

                分组和其他

扩展正则表达式

grep

egrep

 sed

                基本用法

                 sed脚本格式

                 sed常用命令

awk   

                基础用法

                结合sed取IP地址

                awk的内置变量


        

        REGEXP: Regular Expressions,由一类特殊字符及文本字符所编写的模式,其中有些字符(元字符),不表示字符字面意义,而表示控制或通配的功能,类似于增强版的通配符功能,但与通配符不同,通配符功能是用来处理文件名,而正则表达式是处理文本内容中字符

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

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

通配符匹配文件(而且是已存在的文件)

  • 基本正则表达式

  • 扩展正则表达式

可以使用man 7 regex手册帮助

正则表达式之

                元字符

        元字符是一个或一组代替一个或多个字符的字符。

        .   匹配任意单个字符,可以是一个汉字
        []   匹配指定范围内的任意单个字符,示例:[zhou]   [0-9]   []   [a-zA-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 正则表达式会匹配全角空格符
[root@localhost ~]#ls /etc/ |grep rc[.0-6]
#这里点代表字符
rc0.d
rc1.d
rc2.d
rc3.d
rc4.d
rc5.d
rc6.d
rc.d
rc.local
[root@localhost ~]#ls /etc/ |grep rc'\.'
#此处点代表转义
rc.d
rc.local

[root@localhost data]#touch {a..z}.txt
[root@localhost data]#ls
a.txt       b.txt  dns.sh  e.txt  g.txt  i.txt  k.txt  m.txt  o.txt  q.txt  s.txt  u.txt  w.txt  y.txt
[a..z].txt  c.txt  d.txt   f.txt  h.txt  j.txt  l.txt  n.txt  p.txt  r.txt  t.txt  v.txt  x.txt  z.txt
#匹配[]中任意一个字符

[root@localhost data]#ls |grep '[bin].txt'
b.txt
i.txt
n.txt

 #匹配不是a-z.txt文件

[root@localhost data]#ls |grep [^a-z].txt
[a..z].txt
{a-z}.txt
{a-Z}.txt

                表示次数

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

 ##代表前面的o出现3次以上

[root@localhost data]#echo goooooogle |grep 'go\{3,\}gle'
goooooogle

#代表前面o出现2次以上4次以下 

[root@localhost data]#echo google |grep 'go\{2,4\}gle'
google

#代表o匹配任意次 

[root@localhost data]#echo goooooogle |grep go*gle
goooooogle

#一个以上 

[root@localhost data]#echo google |grep "go\+gle"
google

                位置锚定

^行首锚定, 用于模式的最左侧
$行尾锚定,用于模式的最右侧
^PATTERN$用于模式匹配整行 (单独一行  只有root)
^$空行
^[[:space:]]*$空白行
\< 或 \b词首锚定,用于单词模式的左侧(连续的数字,字母,下划线都算单词内部)
\> 或 \b   词尾锚定,用于单词模式的右侧
\<PATTERN\>  匹配整个单词

#过滤出不是已#号开头的非空行

[root@localhost data]#grep "^[^#]" /etc/fstab
/dev/mapper/centos-root /                       xfs     defaults        0 0
UUID=3485d403-cf78-4d1b-92c9-b6025ccacf17 /boot                   xfs     defaults        0 0
/dev/mapper/centos-swap swap                    swap    defaults        0 0

#过滤非空行

[root@localhost data]#grep "^[^$]" /etc/fstab
#
# /etc/fstab
# Created by anaconda on Thu Oct  7 02:46:55 2021
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/centos-root /                       xfs     defaults        0 0
UUID=3485d403-cf78-4d1b-92c9-b6025ccacf17 /boot                   xfs     defaults        0 0
/dev/mapper/centos-swap swap                    swap    defaults        0 0

                分组和其他

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

        后向引用:分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量中,这些变量的命名方式为: \1, \2, \3, ...,\1 表示从左侧起第一个左括号以及与之匹配右括号之间的模式所匹配到的字符

# 分组,分成三组和分成俩组

 #提取ip地址(匹配数字)

[root@localhost data]#ifconfig ens33 |grep netmask|grep -Eo '([0-9]{1,3}.){4}'
192.168.37.102 
255.255.255.0 
192.168.37.255
[root@localhost data]#ifconfig ens33|grep netmask|grep -o '\([0-9]\{1,3\}\.\)\{3\}[0-9]\{3\}'|head -1
192.168.37.102

扩展正则表达式

表示次数

*   匹配前面字符任意次
? 0或1次
+ 1次或多次
{n} 匹配n次
{m,n} 至少m,至多n次
{,n}  #匹配前面的字符至多n次,<=n,n可以为0
{n,} #匹配前面的字符至少n次,<=n,n可以为0

#匹配oo字符和出现g的次数 

 #匹配oo

表示分组

() 分组
分组:() 将多个字符捆绑在一起,当作一个整体处理,如:\(root\)+
后向引用:\1, \2, ...
| 或者  
a|b #a或b
C|cat #C或cat
(C|c)at #Cat或cat

看了扩展正则表达式是不是可以忘记普通正则表达式了,还是扩展正则表达式简单一点

grep

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

  • -i:查找时忽略大小写

  • -v:反向查找,输出与查找条件不相符的行

  • -o 只显示匹配项

  • -f 对比两个文件的相同行

  • -c 匹配的行数

egrep

        egrep命令作用是在文件内查找指定的字符串。

        egrep执行效果与grep -E相似,使用的语法及参数可参照grep指令,与grep的不同点在于解读字符串的方法。

        egrep命令为 grep 的扩充版本, 改良了许多传统 grep 不能或不便的操作. 比方说:
        grep之下不支持 ? 与 + 这两种modifier, 但egrep可以。
        grep不支持 a|b 或 (abc|xyz) 这类”或一”比对, 但egrep可以。
        grep在处理 {n,m} 时, 需用 \{ 与 \} 处理, 但egrep则不需要。

常用参数:

-i搜索时,忽略大小写
-c只输出匹配行的数量
-l只列出符合匹配的文件名,不列出具体的匹配行
-n列出所有的匹配行,显示行号
-h查询多文件时不显示文件名
-s不显示不存在、没有匹配文本的错误信息
-v显示不包含匹配文本的所有行
-w匹配整词
-x匹配整行
-r递归搜索
-q禁止输出任何结果,已退出状态表示搜索是否成功
-b打印匹配行距文件头部的偏移量,以字节为单位
-o与-b结合使用,打印匹配的词据文件头部的偏移量,以字节为单位

 sed

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

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

                基本用法

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

默认将输入结果输出,回车即可

[root@localhost data]#sed " "
aa            
aa
aa
aa
vv
vv
b
b
ffgd
ffgd

 

 查看文件内容,也支持重定向

 

                 sed脚本格式

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

命令

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

sed自带打印功能,比如10排序,p又打印一边

[root@localhost data]#seq 10 |sed 'p'
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
9
9
10
10

#-n关闭打印功能

[root@localhost data]#seq 10 |sed -n 'p'
1
2
3
4
5
6
7
8
9
10

#直接显示第二行内容

[root@localhost data]#ifconfig ens33 |sed -n '2p'
        inet 192.168.37.102  netmask 255.255.255.0  broadcast 192.168.37.255

#还可以截取第几行到第几行

[root@localhost data]#cat xiao.txt |sed -n '3,6p'


\jji
kl
#3往后加6行

[root@localhost data]#cat xiao.txt |sed -n '3,+6p'


\jji
kl


love 
#奇数偶数表示

[root@localhost data]#seq 10 |sed -n '1~2p'
1
3
5
7
9
[root@localhost data]#seq 10 |sed -n '0~2p'
2
4
6
8
10
#d选项删除

[root@localhost data]#seq 10 |sed  '3d'
1
2
4
5
6
7
8
9
10
[root@localhost data]#seq 10 |sed  '3,5d'
1
2
6
7
8
9
10

#还可以直接替换,c,a是追加

[root@localhost data]#seq 10 |sed '2ccc'
1
cc
3
4
5
6
7
8
9
10

[root@localhost data]#seq 10 |sed '2aa'
1
2
a
3
4
5
6
7
8
9
10

                 sed常用命令

参数说明

-e<script>或--expression=<script>以选项中指定的script来处理输入的文本文件。
-f<script文件>或--file=<script文件>以选项中指定的script文件来处理输入的文本文件。
-h或--help 显示帮助。
-n或--quiet或--silent 仅显示script处理后的结果。
-V或--version 显示版本信息。

动作说明

a新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)~
c取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!
d删除,所以 d 后面通常不接任何东西;
i插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);
p打印,亦即将某个选择的数据印出。通常 p 会与参数 sed -n 一起运行~
s取代,可以直接进行取代的工作哩!通常这个 s 的动作可以搭配正规表示法!用法 s/old/new/g 
/PATH/FILE 将替换成功的行保存至文件中

例如替换,将root替换为admin

[root@localhost data]#sed 's/root/admin/g' /etc/passwd |head

 #替换文本字符

[root@localhost data]#cat xiao.txt 
123
345
678

890
895
[root@localhost data]#sed -i -e 's/123/cba/' xiao.txt 
[root@localhost data]#cat xiao.txt 
cba
345
678

890
895

awk   

        awk:Aho, Weinberger, Kernighan,报告生成器,格式化文本输出,GNU/Linux发布的AWK目前由自

        由软件基金会(FSF)进行开发和维护,通常也称它为 GNU AWK

工作原理

        前面提到 sed 命令常用于一整行的处理,而 awk 比较倾向于将一行分成多个“字段”然后再进行处理,且默认情况下字段的分隔符为空格或 tab 键。awk 执行结果可以通过 print 的功能将字段数据打印显示。

格式

awk [选项] ‘模式条件{操作}’ 文件1 文件2....
awk -f|-v 脚本文件 文件1 文件2.....

模式:
未指定表示 为空

/1/2/代表正则表达式

关系表达式

                基础用法

常用命令

-F指定输入时用到的字段分隔符
-v自定义变量
-f从脚本中读取awk命令
-m对val值设置内在限制

和sed一样都可以打印一遍

[root@localhost data]#awk '{print}'
12
12
45
45
lve
lve
love
love
 [root@localhost data]#awk '{print "hello"}'

#字符串需要添加双引号,单引号已被使用,数字不需要
1
hello
1
hello
2
hello
3
hello
4
hello

#BEGIN比较特殊值打一行

[root@localhost data]#awk 'BEGIN {print "hello"}'
hello
#指定冒号作为分隔符,打印第一列和第三列

[root@localhost data]#cat /etc/passwd|awk -F: '{print $1,$3}'|head 
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8
operator 11
 

查看磁盘已用空间

[root@localhost data]#df
Filesystem              1K-blocks    Used Available Use% Mounted on
/dev/mapper/centos-root  39044480 5681088  33363392  15% /
devtmpfs                  1916728       0   1916728   0% /dev
tmpfs                     1932652       0   1932652   0% /dev/shm
tmpfs                     1932652   17452   1915200   1% /run
tmpfs                     1932652       0   1932652   0% /sys/fs/cgroup
/dev/sda1                19520512  182412  19338100   1% /boot
tmpfs                      386532      44    386488   1% /run/user/0
/dev/sr0                  4414592 4414592         0 100% /run/media/root/CentOS 7 x86_64
/dev/sdb                 20961280   32944  20928336   1% /mnt

[root@localhost data]#df|awk -F"( +|%)" '{print $5}'
Use
15
0
0
1
0
1
1
100
1

                结合sed取IP地址

[root@localhost data]#ifconfig ens33 |sed -n '2p' |awk '{print $2}'
192.168.37.102
[root@localhost data]#ifconfig ens33 |awk /netmask/'{print $2}'
192.168.37.102

#$0代表全部元素

[root@localhost data]#awk -F: '{print $0}' /etc/passwd

 #$1代表第一列

[root@localhost data]#awk -F: '{print $1}' /etc/passwd

#已root为开头的行 

[root@localhost data]#awk '/^root/{print}' /etc/passwd
root:x:0:0:root:/root:/bin/bash

#统计当前已/bin/bash结尾的行 

[root@localhost data]#grep -c "/bin/bash$" /etc/passwd 
2


#  BEGIN{}模式表示,在处理指定的文本前,需要先执行BEGIN模式中的指定动作; awk再处理指定的文本,之后再执行END模式中的指定动作,END{}语句中,一般会放入打印结果等语句

 一共查找了42次

[root@localhost data]#awk 'BEGIN {x=0};/\/bin\/bash$/;{x++};END{print x}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
xiaobin:x:1000:1000:xiaobin:/home/xiaobin:/bin/bash
42

                awk的内置变量 ​​​​​​​

FS指定每行文本的字段分隔符,缺省为空格或制表位。与 “-F”作用相同 -v "FS=:"
NF当前处理的行的字段个数
NR当前处理的行的行号(序数)
$0当前处理的行的整行内容
$n当前处理行的第n个字段(第n列)
FILENAME被处理的文件名
RS行分隔符。awk从文件上读取资料时,将根据RS的定义就把资料切割成许多条记录,而awk一次仅读入一条记录进行处理。预设值是\n

FS

[root@localhost data]#awk -v FS=: '{print $1FS$3}' /etc/passwd

#此处FS 相当于于变量

 

两者相同 

 [root@localhost data]#awk -F: '{print $1":"$3}' /etc/passwd

 

NF

[root@localhost data]#awk -F: '{print NF}' /etc/passwd
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
 [root@localhost data]#awk -F: '{print $NF}' /etc/passwd

匹配最后一个字段

#倒数第二行 

 [root@localhost data]#df|awk -F "[ %]+" '{print $(NF-1)}'
Mounted
15
0
0
1
0
1
1
7
1

 NR

#行号

[root@localhost data]#awk '{print NR,$1}' /etc/passwd

#只取第三行第一个字符

[root@localhost data]#awk 'NR==3{print $1}' /etc/passwd
daemon:x:2:2:daemon:/sbin:/sbin/nologin
 #取行间 大于5小于10

[root@localhost data]#seq 10|awk 'NR>5 && NR<10'
6
7
8
9
 

最后一道面试题 

统计/etc/fstab文件中每个单词出现的次数

[root@localhost data]#grep -Eo "\b[[:alpha:]]+\b" /etc/fstab |sort |uniq -c
      1 Accessible
      1 anaconda
      1 and
      1 are
      1 blkid
      1 boot
      2 by
      2 centos
      1 Created
      3 defaults
      3 dev
      1 disk
      1 etc
      1 filesystems
      1 findfs
      1 for
      2 fstab
      1 info
      1 maintained
      1 man
      2 mapper
      1 more
      1 mount
      1 Oct
      1 on
      1 or
      1 pages
      1 reference
      1 root
      1 See
      3 swap
      1 Thu
      1 under
      1 UUID
      2 xfs

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小柏ぁ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值