Linux系统Shell脚本第五章:shell数组、正则表达式及文件三剑客之AWK

目录

一、shell数组

1、数组分类

2、定义数组方法

二、正则表达式

1、元字符

2、表示次数

3、位置锚定

4、分组

5、扩展正则表达式

三、文本三剑客之AWK

1、awk

2、使用格式

3、处理动作

4、选项

4、处理模式

6、if条件判断

 

 

 

 

 

一、shell数组
1、数组分类
①关联数组:必须声明才可以使用,命令:delare -A 数组名

②普通数组:利用数字下标节约变量,可以不声明也可以声明,命令:delare -a 数组名

delare -a命令也可查看有哪些普通数组

2、定义数组方法
①普通数组

数组名=(vlaue0 vlaue1 vlaue2 ...)

[root@pc1 ~]#a=(10 20 30) #定义数组a,值为10 20 30
[root@pc1 ~]#echo ${a[0]} #输出数组a下标为0的元素
10
[root@pc1 ~]#echo ${a[@]} #输出数组a中所有的元素
10 20 30
[root@pc1 ~]#echo ${a[*]} #输出数组a中所有的元素
10 20 30
[root@pc1 ~]#echo ${#a[@]} #输出数组a中元素的个数
3
[root@pc1 ~]#echo ${!a[@]} #输出数组a中元素的下标
0 1 2
[root@pc1 ~]#a[0]=100 #重新定义数组a下标为0的元素为100
[root@pc1 ~]#echo ${a[0]} #输出数组a中下标为0的元素
100

 

②关联数组定义

delare -A 数组名 #声明数组
数组名[下标]=元素 #定义关联数组

[root@pc1 ~]#declare -A f #声明关联数组f
[root@pc1 ~]#f[name]=pc1 #定义关联数组f下标name的元素为pc1
[root@pc1 ~]#f[ip]=10.0.0.0 #定义关联数组f下标ip的元素为10.0.0.0
[root@pc1 ~]#echo ${f[@]} #输出关联数组f的所有元素值
pc1 10.0.0.0
[root@pc1 ~]#echo ${!f[@]} #输出关联数组f中元素的所有下标
name ip

二、正则表达式

注意事项:使用正则表达式必须加引号。

1、元字符

①.:在正则表达式中.表示任意单个字符。

[root@pc1 data]#grep -o r.t /etc/passwd #过滤passwd文件中开头为r中间任意单个字符结尾为t的内容
rat
rat
rat
[root@pc1 data]#grep -o r..t /etc/passwd #过滤passwd文件中开头为r中间任意2个字符结尾为t的内容
root
root
root
root
r/ft
[root@pc1 data]#grep -o r...t /etc/passwd #过滤passwd文件中开头为r中间任意3个字符结尾为t的内容

rtkit

②[  ]:在正则表达式中[ ]表示匹配[ ]中任意一个字符。

[root@pc1 data]#touch {a..c}.txt #创建a-c.txt文件夹
[root@pc1 data]#ls #显示文件夹内容
a.txt b.txt c.txt
[root@pc1 data]#ls |grep '[a-z].txt' #使用grep过滤ls中有任意一个a-z字母.txt的文件
a.txt
b.txt
c.txt

 

 

③[^]:在正则表达式中表示匹配[ ]中外的任意单个字符。 

[root@pc1 data]#touch {a..c}.txt #创建a-c.txt文件
[root@pc1 data]#touch {0..2}.txt #创建0-2.txt文件
[root@pc1 data]#ls #显示文件
0.txt 1.txt 2.txt a.txt b.txt c.txt
[root@pc1 data]#ls |grep '[^0-9].txt' #过滤ls显示文件中除去0-9任意字符.txt文件
a.txt
b.txt
c.txt
[root@pc1 data]#ls |grep '[^a-z].txt' #过滤ls显示文件中除去a-z任意字符.txt文件
0.txt
1.txt
2.txt

 

[:alnum:] 字母和数字
[:alpha:] 代表任何英文大小写字符,亦即 A-Z, a-z
[:lower:] 小写字母,示例:[[:lower:]],相当于[a-z]
[:upper:] 大写字母
[:blank:] 空白字符(空格和制表符)
[:space:] 包括空格、制表符(水平和垂直)、换行符、回车符等各种类型的空白,比[:blank:]包含的范围广
[:cntrl:] 不可打印的控制字符(退格、删除、警铃...)
[:digit:] 十进制数字
[:xdigit:]十六进制数字
[:graph:] 可打印的非空白字符
[:print:] 可打印字符
[:punct:] 标点符号

[root@pc1 data]#echo AB12ab | grep -o '[[:alpha:]]' #过滤输出内容的字母
A
B
a
b
[root@pc1 data]#echo AB12ab | grep -o '[[:alnum:]]' #过滤输出内容的字母和数字
A
B
1
2
a
b
[root@pc1 data]#echo AB12ab | grep -o '[[:lower:]]' #过滤输出内容的小写字母
a
b
[root@pc1 data]#echo AB12ab | grep -o '[[:upper:]]' #过滤输出内容的大写字母
A
B

2、表示次数

①*:表示匹配前面字符任意次,包括0次。

[root@pc1 ~]#echo ac |grep 'ab*c' #ab之间不输入b可匹配
ac
[root@pc1 ~]#echo abc |grep 'ab*c' #ab之间输入1个b可匹配
abc
[root@pc1 ~]#echo abbc |grep 'ab*c'#ab之间输入2个b可匹配
abbc

②.*:表示匹配前面字符任意次,不包括0次。

[root@pc1 ~]#echo ac |grep 'ab.*c' #ac之间不输入b匹配不到
[root@pc1 ~]#echo abc |grep 'ab.*c' #ac之间输入1个b可以匹配
abc
[root@pc1 ~]#echo abbc |grep 'ab.*c' #ac直接输入2个b可以匹配
abbc

③\?:表示匹配前面的字符1次或0次,即可有可无。

[root@pc1 ~]#echo ac | grep 'ab\?c' #ac之间不输入b可以匹配
ac
[root@pc1 ~]#echo abc | grep 'ab\?c' #ac之间输入1个b可以匹配
abc
[root@pc1 ~]#echo abbc | grep 'ab\?c' #ac之间输入2个b匹配不到

④\+:表示匹配前面的字符最少1次。

[root@pc1 ~]#echo ac | grep 'ab\+c' #ac之间不输入b匹配不到
[root@pc1 ~]#echo abc | grep 'ab\+c' #ac之间输入1个b可以匹配
abc
[root@pc1 ~]#echo abbbbc | grep 'ab\+c' #ac之间输入多个b可以匹配
abbbbc

⑤\{n\}:表示匹配前面的字符n次。

[root@pc1 ~]#echo abbbc |grep 'ab\{3\}c' #输出abbbc匹配ac之间b字符出现3次可以匹配
abbbc
[root@pc1 ~]#echo abbbbc |grep 'ab\{3\}c' #输出abbbbc匹配ac之间b字符出现3次匹配不到

⑦\{m,\}:表示匹配前面的字符最少m次。

⑧\{,n\}:表示匹配前面的字符最多n次。

3、位置锚定
①^表示以什么字符开头的行。

②$表示以什么字符为结尾的行。

③^PATTERN$ 表示用于模式匹配整行 (单独一行 只有PATTERN字符)。

④^$ 表示空行。

⑤\< 或 \b #词首锚定,用于单词模式的左侧(连续的数字,字母,下划线都算单词内部)。

⑥\> 或 \b #词尾锚定,用于单词模式的右侧。

⑦\<PATTERN\> #匹配整个单词。

[root@pc1 ~]#cat a.txt #查看a.txt内容
root
abc abd abf abe
asfase
asdfasfewe
[root@pc1 ~]#cat a.txt |grep '^a' #查看a.txt内容过滤以a开头的行
abc abd abf abe
asfase
asdfasfewe
[root@pc1 ~]#cat a.txt |grep 'e$' #查看a.txt内容过滤以e为结尾的行
asfase
asdfasfewe
[root@pc1 ~]#cat a.txt |grep '^root$' #查看a.txt内容过滤只有root字符的行
root
[root@pc1 ~]#cat a.txt |grep '\ba' #查看a.txt过滤以a开头的词
abc abd abf abe
asfase
asdfasfewe
[root@pc1 ~]#cat a.txt |grep 'e\b' #查看a.txt过滤以e为结尾的词
abc abd abf abe
asfase
asdfasfewe
[root@pc1 ~]#cat a.txt |grep -o '\babc\b' #查看a.txt过滤次abc
abc

4、分组

()将多个字符捆绑在一起当做一个整体处理

[root@pc1 ~]#echo abcccc |grep "abc\{4\}" #匹配输出内容c出现4次
abcccc
[root@pc1 ~]#echo abcccc |grep "\(abc\)\{4\}" #abc字符加()分组匹配输出内容abc出现4次,无abc出现4次匹配不到
[root@pc1 ~]#echo abcabcabcabc |grep "\(abc\)\{4\}" #abc字符加()分组匹配输出内容abc出现4次匹配成功
abcabcabcabc

5、扩展正则表达式
①使用方法

grep -E选项加正则表达式内容,与正常正则表达式区别在于不用在匹配时添加 \

②表示次数

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

③表示分组

() 分组

三、文本三剑客之AWK

1、awk

awk为流编辑器,即读取文件一行处理一行。不同于vi编辑器等是将文件整个缓存在内容中处理。

2、使用格式

awk  [选项]   '处理模式{处理动作}'

'{ }'为固定格式

 

举例:取出sda硬盘的容量
[root@pc1 data]#lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 60G 0 disk
├─sda1 8:1 0 2G 0 part /boot
└─sda2 8:2 0 54G 0 part
├─centos-root 253:0 0 50G 0 lvm /
└─centos-swap 253:1 0 4G 0 lvm [SWAP]
sdb 8:16 0 20G 0 disk
sdc 8:32 0 20G 0 disk
sdd 8:48 0 20G 0 disk
sr0 11:0 1 4.2G 0 rom
[root@pc1 data]#lsblk |grep -w sda #通过过滤sda字符将sda此行过滤出
sda 8:0 0 60G 0 disk
[root@pc1 data]#lsblk |grep -w sda | awk '{print $4}' #使用awk不指定分隔符 打印出第4列
60G

3、处理动作
①基本格式:awk [选项] '处理模式{处理动作}'

②print动作:打印,打印'{print $1}'即为打印第一列,'{print $n}'即打印为第n列,'{print $n,$m}'即为打印第n列和第m列。

③print打印顺序:'BEGIN{print "1"} END {print "2"} {print "3"} ',首先打印BEGIN后的print 1,然后打印print 3 最后打印END后的print 2,BEGIN表示第一个打印,END表示最后打印

举例1:
[root@pc1 data]#cat test.txt #创建文件
1 2 3 4 5 6 7 8 @test.txt 文件内容
[root@pc1 data]#awk '{print $1}' test.txt #使用awk处理文件test.txt打印第1列
1
[root@pc1 data]#awk '{print $5}' test.txt #使用awk处理文件test.txt打印第5列
5
[root@pc1 data]#awk '{print $1,$5}' test.txt #使用awk处理文件test.txt打印第1列和第5列
1 5

举例2:
[root@pc1 data]# awk 'BEGIN{print "1"} END{print "$2"} {print "3"}' test.txt
1
3
2

4、选项

①基本格式:awk  [选项]   '处理模式{处理动作}'

②选项若不写默认为以空格为分隔符处理,且会将空格自动压缩。

③-F 选项 指定分隔符,即指定以什么为分隔符处理内容

举例:
[root@pc1 data]#cat test.txt #编辑test.txt内容
one two three
root:lisi:zhangsan
[root@pc1 data]#awk '{print $2}' test.txt #默认过滤test内容以空格为分隔符打印出第2列为two
two
[root@pc1 data]#awk -F : '{print $2}' test.txt #使用-F选项指定以:为分隔符打印出第2列为lisi

lisi

4、处理模式

举例:
[root@pc1 data]#cat test.txt #创建test.txt
root 1 abc 2 3 4 5 6 7 8
abcd

sadfasdf root
[root@pc1 data]#awk '/^root/{print $2}' test.txt #使用awk配合正则表达式打印出test.txt文件中以root为开头的行的第二列,注意处理模式在固定格式'{}'的单引号中
1 #匹配出的内容
[root@pc1 data]#awk '/^root/,/root$/{print $2}' test.txt #使用awk配合正则表达式打印出test.txt文件中以root为开头的且以root结尾的第二列,注意处理模式在固定格式'{}'的单引号中
1


root #匹配出的内容

①基本格式:awk  [选项]   '处理模式{处理动作}'

②处理模式为空表示无其他额外条件。

③正则表达式匹配模式

正则匹配:与正则表达式配合使用。

举例:
[root@pc1 data]#cat test.txt #创建test.txt
root 1 abc 2 3 4 5 6 7 8
abcd

sadfasdf root
[root@pc1 data]#awk '/^root/{print $2}' test.txt #使用awk配合正则表达式打印出test.txt文件中以root为开头的行的第二列,注意处理模式在固定格式'{}'的单引号中
1 #匹配出的内容
[root@pc1 data]#awk '/^root/,/root$/{print $2}' test.txt #使用awk配合正则表达式打印出test.txt文件中以root为开头的且以root结尾的第二列,注意处理模式在固定格式'{}'的单引号中
1


root #匹配出的内容

5、awk常见的内置变量 

比较操作符:==, !=, >, >=, <, <=

逻辑操作符:&&与 并且的关系,||或 或者关系,!非 取反关系

①FS :指定每行文本的字段分隔符,缺省为空格或制表符(tab)。与 “-F”作用相同 -v "FS=:"

[root@pc1 data]#cat a.txt
a:b:c
[root@pc1 data]#awk -v "FS=:" '{print $2}' a.txt 使用FS变量指定:为分隔符打印a.txt文件的第二列
b

②OFS:输出时的分隔符

[root@pc1 data]#cat a.txt
a:b:c
[root@pc1 data]#awk -v "FS=:" -v OFS="==" '{print $1OFS$3}' a.txt 使用FS变量指定:为分隔符且指定输出分隔符OFS为==,打印a.txt文件的第1列和第3列
a==b

③NF:当前处理的行的字段个数即处理行有多少列,默认按空格分列,可指定。

举例
awk -F : '{print NF}' /etc/passwd |head -n 1
#指定:为分隔符打印出文件/etc/passwd第一行有多少个字段,即多少列
7
awk -F : '{print $(NF-1)}' /etc/passwd |head -n 1
#指定:为分隔符打印出文件/etc/passwd第一行的倒数第二个字段,即倒数第二列
/root

 

 ④NR:当前处理的行的行号(序数)

举例
awk -F : 'NR==1{print $1}' /etc/passwd
#指定:为分隔符打印出/etc/passwd文件第一行的第一个变量,注意模式要写在'模式{}'位置
root
awk -F : 'NR>=1 && NR<=3{PRINT $1}' /etc/passwd
#指定:为分隔符打印出/etc/passwd文件大于等于第一行且小于等于第三行的第三个变量
root
bin
daemon

 

 ⑤$0:当前处理的行的整行内容

举例
awk -F : 'NR==1{print $0}' /etc/passwd
#指定:为分隔符打印出文件/etc/passwd第一行的所有内容
root:x:0:0:root:/root:/bin/bash
awk -F : 'NR>=1 && NR<=3{print $0}' /etc/passwd
#指定:为分隔符打印出文件/etc/passwd大于等于第一行且小于等于第三行的所有内容
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin

 

 

⑥$n:当前处理行的第n个字段(第n列)

⑦FILENAME:被处理的文件名

⑧RS:行分隔符。awk从文件上读取资料时,将根据RS的定义就把资料切割成许多条记录,而awk一次仅读入一条记录进行处理。预设值是\n

6、if条件判断

if语句:awk的if语句也分为单分支、双分支和多分支
单分支为if(){}
双分支为if(){}else{}
多分支为if(){}else if(){}else{}

举例
awk -F : '{if($3>1000)print $1,$3}' /etc/passwd
#指定:为分隔符过滤passwd文件第三列如果大于1000则大于出第一列和第三列
nfsnobody 65534

 

posted @ 2023-02-02 08:55  靖安yj  阅读(101)  评论(0编辑  收藏  举报