linux中shell脚本——shell数组、正则表达式及文件三剑客之AWK

  • Post author:
  • Post category:linux



目录


一.shell数组


1.1.数组分类


1.2.定义数组方法


二.正则表达式


2.1.元字符


2.2.表示次数


2.3.位置锚定


2.4.分组


2.5.扩展正则表达式


三.文本三剑客之AWK


3.1.awk介绍及使用格式


3.2.处理动作


3.3.awk选项


3.4.awk处理模式


2.5.awk常见的内置变量


2.6.if条件判断


一.shell数组

1.1.数组分类



关联数组

:必须声明才可以使用,命令:delare  -A   数组名

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

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


1.2.

定义数组

方法


(1)普通数组

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


(2)关联数组定义

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

二.正则表达式

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

2.1.元字符


(1).:在正则表达式中.表示任意单个字符

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


(2)[  ]:在正则表达式中[ ]表示匹配[ ]中任意一个字符

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


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

[root@zrsb  data]#touch {a..c}.txt        #创建a-c.txt文件
[root@zrsb  data]#touch {0..2}.txt        #创建0-2.txt文件
[root@zrsb  data]#ls                      #显示文件
0.txt  1.txt  2.txt  a.txt  b.txt  c.txt
[root@zrsb  data]#ls |grep '[^0-9].txt'   #过滤ls显示文件中除去0-9任意字符.txt文件
a.txt
b.txt
c.txt
[root@zrsb  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@zrsb  data]#echo AB12ab | grep -o '[[:alpha:]]'  #过滤输出内容的字母
A
B
a
b
[root@zrsb  data]#echo AB12ab | grep -o '[[:alnum:]]'  #过滤输出内容的字母和数字
A
B
1
2
a
b
[root@zrsb  data]#echo AB12ab | grep -o '[[:lower:]]'  #过滤输出内容的小写字母
a
b
[root@zrsb  data]#echo AB12ab | grep -o '[[:upper:]]'  #过滤输出内容的大写字母
A
B

2.2.表示次数


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

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


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

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


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

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


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

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


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

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


(6)\{m,n\}:表示匹配前面的字符最少m次最多n次。

[root@zrsb ~]#echo abc |grep 'ab\{1,3\}c'  #输出abc匹配ac之间b出现最少1次最多3次可以匹配
abc
[root@zrsb  ~]#echo abbc |grep 'ab\{1,3\}c' #输出abbc匹配ac之间b出现最少1次最多3次可以匹配
abbc
[root@zrsb  ~]#echo abbbc |grep 'ab\{1,3\}c'#输出abbbc匹配ac之间b出现最少1次最多3次可以匹配
abbbc
[root@zrsb  ~]#echo abbbbc |grep 'ab\{1,3\}c'#输出abbbbc匹配ac之间b出现最少1次最多3次匹配不到

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

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

2.3.位置锚定

(1)^表示以什么字符开头的行。

(2)$表示以什么字符为结尾的行。

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

(4)^$ 表示空行。

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

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

(7)\<PATTERN\>    #匹配整个单词。

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

2.4.分组

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

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

2.5.扩展正则表达式

(1)使用方法

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

(2)表示次数

*   匹配前面字符任意次

? 0或1次

+ 1次或多次

{n} 匹配n次

{m,n} 至少m,至多n次

{,n}  #匹配前面的字符至多n次,<=n,n可以为0

{n,} #匹配前面的字符至少n次,<=n,n可以为0

(3)表示分组

() 分组

三.文本

三剑客

之AWK

3.1.awk介绍及使用格式

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

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

‘{ }’为固定格式

举例:取出sda硬盘的容量
[root@zrsb 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@zrsb data]#lsblk  |grep -w sda       #通过过滤sda字符将sda此行过滤出
sda               8:0    0   60G  0 disk 
[root@zrsb data]#lsblk  |grep -w sda | awk '{print $4}' #使用awk不指定分隔符 打印出第4列
60G

3.2.处理动作

(1)基本格式:awk  [选项]   ‘处理模式{处理动作}’

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

(3)print打印顺序:’BEGIN{print “1”} END {print  “2”}  {print “3”} ‘,首先打印BEGIN后的print 1,然后打印print 3  最后打印END后的print 2,BEGIN表示第一个打印,END表示最后打印

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

3.3.awk选项

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

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

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

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

3.4.awk处理模式

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

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

③正则表达式匹配模式

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

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

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

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

2.5.awk常见的内置变量

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

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


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

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


(2)OFS:输出时的分隔符

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


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

awk -F : '{print NF}'  /etc/passwd  |head -n 1
#指定:为分隔符打印出文件/etc/passwd第一行有多少个字段,即多少列

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


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

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


(5)$0:当前处理的行的整行内容

awk -F : 'NR==1{print $0}' /etc/passwd
#指定:为分隔符打印出文件/etc/passwd第一行的所有内容


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

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

(7)FILENAME:被处理的文件名

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

2.6.if条件判断

if语句:awk的if语句也分为单分支、双分支和多分支
单分支为if(){}
双分支为if(){}else{}
多分支为if(){}else if(){}else{}
awk -F : '{if($3>1000)print $1,$3}' /etc/passwd
#指定:为分隔符过滤passwd文件第三列如果大于1000则大于出第一列和第三列



版权声明:本文为Personal_Liberty原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。