shell编程-正则表达式与文本处理器sedawk

Posted 可乐卷儿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shell编程-正则表达式与文本处理器sedawk相关的知识,希望对你有一定的参考价值。

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

一、正则表达式

1、定义

  • 又称正规表达式、常规表达式
  • 使用字符串来描述、匹配一系列符合某个规则的字符串
  • 正则表达式组成
    • 普通字符
      • 大小写字母、数字、标点符合及其一些其他符号
    • 源字符
      • 在正则表达式中具有特殊意义的专用字符

2、正常表达式层次

2.1、基础正则表达式

基础正则表达式即常用的正则表达式部分
除了普通字符外,常见的以下元字符

\\ :转义符;\\n:换行;!:非
^:匹配以...开头
$:匹配以...结尾
^$:匹配空格
.:匹配出\\n(换行)之外的任意的一个字符
*:取决于前面一个字符,代表前面一个字符0次或多次
.*:任意长度的字符,*取决于.的字符
[ ]:匹配指定范围内的单个或多个字符
[^]:匹配任意不在列表中的单个或一组字符;是区分大小写的
^[]:匹配指定范围内的单个或多个字符开头
^[^]:匹配任意不在列表中的单个或一组字符
\\{n\\}:匹配前面的字符出现n次
\\{n,\\}:匹配前面的字符至少n次
\\{,m\\}:匹配前一个字符最多出现m次
\\{n,m}:匹配前面的字符n到m次
\\<  :匹配以....开头的行
\\>  :匹配以....结尾的行
\\<......\\>:匹配某一个单词的行;精确匹配

实例
在这里插入图片描述

a-zA-Z:所有大小写字母
a-zA-Z0-9:所有大小写字母和数字

echo ABC/0 | grep [ ^a-zA-Z0-9] ## 匹配出特殊字符

\\{n,m}:匹配前面的字符n到m次
\\{n\\}:匹配前面的字符出现n次

echo good | grep “go{1,3}d”
echo god | grep “go{1}d”
在这里插入图片描述

\\{n,\\}:匹配前面的字符至少n次在这里插入图片描述
在这里插入图片描述

2.2、扩展正则表达式

扩展正则表达式是对基础正则表达式的扩充深化
扩展元字符如下

+:匹配前面字符至少1次以上;精确匹配

在这里插入图片描述

?:匹配前面字符0次或者1次 

在这里插入图片描述

():将括号中的字符串作为一个整体
|:或

在这里插入图片描述

{n}:前一个字符重复n次
{n,}:前一个字符至少重复n次
{n,m}:前一个字符出现n-m次

在这里插入图片描述
查找网卡配置文件里面的ip地址
在这里插入图片描述


文本处理器三大剑客:grep、sed、awk;前面已经详细讲解了grep,这里就不做介绍了

二、文本处理器-sed

1、定义

sed 命令:按行操作,与单引号一起使用‘’;利用脚本来处理文本文件。无交互式的修改替换文件,它可以依照脚本的指令来处理、编辑文本文件。主要用来自动编辑一个或多个文件、简化对文件的反复操作、编写转换程序等。

2、工作原理

  1. 读入新的一行内容到缓存空间;
  2. 从指定的操作指令中取出第一条指令,判断是否匹配pattern(模式);
  3. 如果不匹配,则忽略后续的编辑命令,回到第2步继续取出下一条指令;
  4. 如果匹配,则针对缓存的行执行后续的编辑命令;完成后,回到第2步继续取出下一条指令;
  5. 当所有指令都应用之后,输出缓存行的内容;回到第1步继续读入下一行内容;
  6. 当所有行都处理完之后,结束

3、命令格式

sed 选项 模式匹配 文件名

在这里插入图片描述

4、常用选项

常用选项含义
-e进行多次编辑
-n取消默认输出
-f指定sed文件名
-i直接在源文件中修改
-r使用扩展正则表达式
命令动作含义
p打印输出
d删除指定行
a在指定行后面插入内容
r读入其他文件内容到当前文件,并不会保存
w指定当前文件的内容写入另一个文件
c替换整行
s搜索替换(局部)
s/ /g搜索替换(全局)
s/ /i不区分大小写替换
=打印行号
i更改源文件

1. 打印输出-“-n与p”

-n    #取消默认输出
p    #打印输出  两者一般结合使用

sed ‘p’ yy.txt ## 逐行打印,但是会打印2遍,一般p与-n结合使用
在这里插入图片描述
sed -n ‘1p’ yy.txt ## ‘1p’:打印第一行
sed -n ‘3p’ yy.txt ## ‘3p’:打印第三行
sed -n ‘1,3p’ yy.txt ## “,”逗号是连续,‘1,3p’:打印1-3行
在这里插入图片描述
sed -n ‘1,+4p’ ##打印1-4行;其中’1,+4p’=‘1,4p’
在这里插入图片描述
sed -n ‘0~2p’:打印偶数行;从第一行开始,间隔2行打印
sed -n ‘1~2p’:打印奇数行;从第0行开始,间隔2行打印
cat -n yy.txt | sed -n ‘1~2p’
在这里插入图片描述
sed -n ‘$p’:打印最后一行
在这里插入图片描述

sed -n ‘2p;3p’ ##打印第二行和第三行;分号“;”是间隔
在这里插入图片描述
sed -n ‘/^root/p’ ##打印root开头的行
sed -n ‘/bash$/p’ ##打印bash结尾的行
在这里插入图片描述

sed -n ‘/^root|bash$/p’ ##打印root开头bash结尾的行;这里的“|”代表或,需要使用转义符“/”
在这里插入图片描述

sed -n ‘/^$/p’ yy.txt #打印空格
在这里插入图片描述
‘/ /p’:打印出有空格的行
在这里插入图片描述
打印出/bin/bash的行
在这里插入图片描述
2. 使用扩展正则表达式-“-r”

sed默认不支持扩展正则,如果要支持,需要加-r选项
-r:使用扩展正则表达式;匹配扩展元字符时,使用此选项,无须使用转义符
在这里插入图片描述

3. 多条命令时使用-“-e:或”

sed -ne ‘/^root/p’ -e ‘/nologin$/p’ yy.txt #打印yy.txt文件内root开头或者nologin结尾的行
在这里插入图片描述
sed -ne ‘2p’ -e ‘4p’ yy.txt ##打印第二行或者第四行
在这里插入图片描述
4. 删除-“d”

'd' ##删除指定行;精确匹配字母大小写
'Id' ##删除指定行;忽略字母大小写
'$d':删除最后一行

cat -n yy.txt | sed ‘4d’ ##删除第四行
cat -n yy.txt | sed ‘/root/d’ ##删除root的行
在这里插入图片描述
5. 搜索替换-"s"

可以自定义分隔符;把字符串内的某些字符替换

sed -n ‘s#/bin/bash#bbb#p’ yy.txt
sed -n ‘s,/bin/bash#bbb,p’ yy.txt
sed -n ‘s@/bin/bash#bbb@p’ yy.txt
sed -n ‘s#/bin/bash#/sbin/nologin#p’ yy.txt
在这里插入图片描述
在这里插入图片描述

's':局部替换
'g':全局替换
's/ /i':不区分大小写  或者I(大写):不区分大小写

在这里插入图片描述
‘s/^#/ /p’:#开头的行替换成空格
在这里插入图片描述
给12两行开头替换成#
在这里插入图片描述
&符号;&=root,root前面需要加#
在这里插入图片描述
():当做位置变量使用,当有多个字符需要匹配时,括号内容保留替换
在这里插入图片描述
echo hello world gg | sed -nr ‘s/(hello) (world) (gg)/\\2 \\3 \\1/p’
在这里插入图片描述
echo hello world gg | sed -nr ‘s/(hello) (world)/\\2 the \\1/p’
在这里插入图片描述
在这里插入图片描述
6. 替换整行-‘c’

后面所有的内容识别成整体的内容
在这里插入图片描述
sed ‘/root/chello eorld;3p’ zz.txt :root替换成hello world;3p
在这里插入图片描述
7. 打印行号-“=”

sed ‘=’ yy.txt #打印文件的行号
在这里插入图片描述
‘$=’:最后一行
在这里插入图片描述
sed是逐行匹配
打印第三行内容和最后一行
在这里插入图片描述
sed -n ‘2=;3p’ yy.txt ##打印第二行行号和第三行内容
在这里插入图片描述
打印前五行
在这里插入图片描述
8. 增加内容-“a”“i”

‘a’:某一行的下面
'i':某一行的上面

在这里插入图片描述

'1a':在第一行后面插入

在这里插入图片描述
添加ip地址
在这里插入图片描述
以root开头后面插入ip地址
在这里插入图片描述
1-3行插入ip地址
在这里插入图片描述
9. 更改源文件-“-i”
在这里插入图片描述
-i.bak:备份源原件,并更改源文件内容
在这里插入图片描述
10. 插入其他文件内容

‘r’:读入其他文件内容到当前文件,并不会保存
‘1r’:第一行后面插入
‘$r’:最后一行插入
‘3r’:第三行后面插入
sed ‘3r /etc/hosts’ yy.txt 在yy.txt第三行插入/etc/hosts
在这里插入图片描述
11. 写入另一个文件-“w”
指定当前文件的内容写入另一个文件,再次追加其他文件内容会覆盖掉原本的内容
zz.txt的第一行写入/etc/hosts
在这里插入图片描述

5、通过调用文件执行操作-“-f”

新建一个sed脚本
在这里插入图片描述
开头写
#!/bin/sed -f
只需要把模式匹配内容写入
在这里插入图片描述
在这里插入图片描述
脚本内容可以逐行写入,若要在一行,中间分号“;”间隔
sed -f sed.sh p.txt


三、文本处理器-awk

1、概述

AWK是一种处理文本文件的语言,是一个强大的文本分析工具。
它是专门为文本处理设计的编程语言,也是行处理软件,通常用于扫描、过滤、统计汇总工作数据可以来自标准输入也可以是管道或文件;缺点是不能替换,修改文件
20世纪70年代诞生于贝尔实验室,现在centos7用 的是gawk
之所以叫AWK是因为其取了三位创始人Alfred Aho, Peter Weinberger, 和Brian Kernighan 的Family Name的首字符。

2、工作原理

当读到第一行时,匹配条件,然后执行指定动作,再接着读取第二行数据处理,不会默认输出
如果没有定义匹配条件默认是匹配所有数据行,awk隐含循环,条件匹配多少次动作就会执行多少次
格式:

awk关键字  选项    命令部分  '{xxxxxx}'

awk ‘{print}’ p.txt ##打印p.txt文本文件所有行
在这里插入图片描述

3、内置变量

$0:代表整行
$1:代表第一列
$2:代表第二列
$n:n代表数字1/2/3....;位置变量n
NF:列数,打印每行有多少列
NR:显示行号
FS:指定分隔符,默认为空白字符
OFS:定义了输出时的分隔符号,以什么分隔指定文件
RS:指定切割行的符号
ORS:指定什么连接行,指定输出的换行符
-F:  ##指定分隔符

默认以空格或tab键作为分隔符分隔行
脚本文件加入两行带有空格和tab键的内容
在这里插入图片描述

3.1、变量实例

1. $1:位置变量1
在这里插入图片描述
awk -F: ‘{print $1}’ p.txt ##指定分隔符分号打印
在这里插入图片描述
awk -F/ ‘{print $1}’ p.txt ##指定分隔符/
awk -Fx ‘{print $1}’ p.txt ##指定分隔符x
在这里插入图片描述
打印多列;内置变量中间加逗号“,”
awk -F: ‘{print $1,$2}’ p.txt ##分号分隔符打印2列
在这里插入图片描述
内置变量中间加双引号“ ”,双引号内可任意设置符号
awk -F: ‘{print $1" " $2}’ p.txt
在这里插入图片描述
awk -F: ‘{print $1"–" $2}’ p.txt ##双引号加–
在这里插入图片描述
双引号内加入制表符 :\\t
在这里插入图片描述
打印用户名的root的uid是0
awk -F: ‘{print “用户名”$1"的uid是"$3}’ p.txt
在这里插入图片描述
2. $0:代表整行
awk -F: ‘{print $0}’ p.txt #以分隔符:打印整行
在这里插入图片描述
awk -F: ‘{print $0,$1,$2}’ p.txt ##打印整行的基础上,打印第一列和第二列
在这里插入图片描述
3. NF:列数,打印每行有多少列
awk -F: ‘{print NF}’ p.txt
在这里插入图片描述

$NF ##打印最后一列
awk -F: ‘{print $NF}’ p.txt
在这里插入图片描述
4. NR:显示行号
awk -F: ‘{print NR}’ p.txt
在这里插入图片描述
awk -F: ‘{print NR,$0}’ p.txt ##打印行号并输出行号;友好显示
在这里插入图片描述
也可以用于备份,写入其他文件
在这里插入图片描述


-F/NR/NF 综合实例 awk -F: '{print NR"\\t"$0}' p.txt ##打印整行并输出行号 awk -F[:/] '{print NF}' p.txt ##以:和/分割,并显示列数

在这里插入图片描述
以bin开头的那一行第一列
awk -F: ‘/^bin/{print $1}’ p.txt
在这里插入图片描述
awk -F: ‘/sbin/{print $0}’ p.txt ##包含sbin的行
在这里插入图片描述
awk -F: ‘/sbin/{print NR,$0}’ yy.txt ##打印包含sbin,显示行号打印整行
在这里插入图片描述

awk -F: ‘/sync$/{print NR,$0}’ yy.txt ##打印snyc结尾,显示行号,打印整行
在这里插入图片描述
awk -F: ‘/[oa]/{print NR,$0}’ yy.txt ##打印包含o或者a,显示行号,打印整行
在这里插入图片描述

3.2、awk的流程控制BEGIN和END

逐行执行开始之前执行什么任务,结束之后再执行什么任务,用BEGIN、END
BEGIN:用来做初始化操作,仅在读取数据记录之前执行一次
END:用来做汇总操作,仅在读取完数据记录之后执行一次
- BEGIN

  • 可以直接做运算
[root@klj ~]# awk 'BEGIN{print 1+1}'
2
[root@klj ~]# awk 'BEGIN{print 1-1}'
0
[root@klj ~]# awk 'BEGIN{print 2**3}'
8
[root@klj ~]# awk 'BEGIN{print 2/3}'
0.666667
[root@klj ~]# awk 'BEGIN{print 2%3}'
2
  • 使用变量时
[root@klj ~]# x=2
[root@klj ~]# awk 'BEGIN{print '$x'}'
2
[root@klj ~]# awk 'BEGIN{print "'$x'"}'
2 

[root@klj ~]# awk 'BEGIN{x=2;x++;print x}' 
3
[root@klj ~]# awk 'BEGIN{;x++;print x}'   ##没有给x赋值,默认是0
1
  • END
    awk ‘END{print NR,$0}’ p.txt ##打印最后一整行
    在这里插入图片描述
    awk ‘BEGIN{FS=":"}{print $1}’ p.txt ##开始时定义分隔符为冒号,打印第一列
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    awk ‘BEGIN{RS=" "}{print}’ p.txt ##RS:以回撤分隔
    awk ‘BEGIN{ORS=" "}{print}’ p.txt ##ORS:以空格分隔
    在这里插入图片描述
    awk ‘BEGIN{RS=“x”}{print}’ p.txt ##碰到x就换行
    在这里插入图片描述
    awk ‘BEGIN{ORS="------"}{print}’ p.txt ##以“------”连接内容
    在这里插入图片描述
    还可以做逻辑判断
    awk ‘NR>3 && NR<10{print NR,$0}’ p.txt ##打印4-9行一整行内容,并打印出行号
    在这里插入图片描述
    awk ‘NR<10 || NR>20{print NR,$0}’ p.txt ## 打印1-9行或者大于20行的

    seq 100 | awk ‘$1~/7/{print $1}’ ##打印出1-100内包含7的数
    seq 100 | awk ‘$1~/7/ && $1%7==0 {print $1}’ ## 打印出1-100内包含7的数并且可以被7整除的数
    在这里插入图片描述

3.3、awk内的if语句

固定格式

单分支为if() {}
双分支为if(){}else{}
多分支为if(){}else if(){}else{}

实例
awk -F: ‘{if($3>1000){print $3}}’ /etc/passwd
在这里插入图片描述
awk -F: ‘{if($3>1000){print $0}else{print $1}}’ /etc/passwd ##第三列大于1000,打印整行,否则打印第一列
在这里插入图片描述

4、结合特殊符号-“~ ” 、“!~”

~    ##模糊匹配;非精确匹配
!~   ##非

实例:
awk -F: ‘/sbin/{print NR,$0}’ p.txt
awk -F: ‘$1~/mail/{print $NF}’ p.txt ##匹配第一列是mail,并输出最后一列
在这里插入图片描述
awk -F: ‘NR~/3/{print NR,$0}’ /etc/shadow ##打印shadow文件内包含3的内容
在这里插入图片描述

awk -F: ‘KaTeX parse error: Expected '}', got 'EOF' at end of input: …/dae/{print NR,NF}’ yy.txt ##打印不是dea开头的第五列,并显示行号
在这里插入图片描述
awk -F: ‘$2~/!/{print NR,$1}’ /etc/shadow ##输出shadow文件中以冒号分隔的第二列有感叹号的行的内容
在这里插入图片描述

5、精确匹配-“=”、“>=”、“字符串”

==:等于;精确匹配
>=:大于等于;精确匹配
“字符串”:精准匹配一个字符串,需要双引号

实例
awk -F: ‘NR1{print $0}’ p.txt ##打印出第一整行内容
在这里插入图片描述
awk -F: ‘NR>=33{print NR,$0}’ /etc/shadow ##精确匹配大于等于33行并输出内容
在这里插入图片描述
awk -F: '$1
"ntp"{print NR,$0}’ /etc/shadow ##打印ntp开头的那一行,并显示行号
在这里插入图片描述
awk -F:: ‘NR1{print NF,$0}’ /etc/shadow ##打印出第一行,并以::分隔显示列数
在这里插入图片描述
ifconfig ens33 | awk ‘/netmask/{print “ip:”$2}’ ##精确输出本机ip地址
在这里插入图片描述
df -h | awk 'NR
2{print"avil:"$4}’ ## 打印第二行第四列
在这里插入图片描述
free -m | awk ‘NR2{print"free:"$4}’ ##打印第二行第四列
free -m | awk 'NR
2{print"free:"$3}’ ##打印第二行第三列
free -m | awk ‘NR==3{print"free:"$3}’ ##打印第三行第三列
在这里插入图片描述

以上是关于shell编程-正则表达式与文本处理器sedawk的主要内容,如果未能解决你的问题,请参考以下文章

shell编程之正则表达式与文本处理器

shell编程之正则表达式与文本处理器

Shell编程之正则表达式

shell脚本之正则表达式

Shell 编程 正则表达式

05 shell编程之正则表达式