shell脚本知识点14

Shell-day14

1. 昨日回顾


1. Shell正则表达式 

2. 什么是正则表达式

3. 常见的通配符和特殊符号

4. 正则表达式的符号介绍   基础正则  扩展正则 

5. 正则表达式之Grep应用  

6. 正则表达式之Sed应用  工作原理  

2. Awk基本介绍


awk是一种编程语言    gawk    对于底层的操作系统的文本及数据处理 


awk处理数据的方式:

1. 读入文件,按行进行读取,从第一行到最后一行 

2. 寻找匹配的条件的行,在行上进行操作mysql主从同步及读写分离配置

3. 如果此行没有满足条件的,会丢弃,没有指定条件的,会把当前行内容全部打印出来 

awk的语法

awk  [option]  'command'  files


#处理模式


行处理前      行处理中     行处理后

BEGIN{}      {}  		 END{}

[root@qls ~]# awk 'BEGIN{print 1+1}{print $3}END{print "命令结束"}'  /etc/hosts
2			#行处理前的执行结果 
localhost.localdomain		#行处理中执行的结果
localhost.localdomain		#行处理中执行的结果
命令结束	  #行处理后的结果  这里是输出所有行处理完成后的最后结果

#行处理前

[root@qls ~]# awk 'BEGIN{print 1+1}'
2

#行处理中 
[root@qls ~]# awk 'NR==1' number.txt
1

[root@qls ~]# awk '/root/' passwd 
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

#行处理前+行处理中 

[root@qls ~]# awk '{print $3}'  /etc/hosts     #分隔符  默认的分隔符 
localhost.localdomain
localhost.localdomain

[root@qls ~]# awk -F: '{print $1}' passwd	#简略的一种写法
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator

[root@qls ~]# awk 'BEGIN{FS=":"}{print $1}'  passwd	#完整写法  
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator

#行处理前+行处理中+行处理后

[root@qls ~]# awk '{Sum+=$1}END{print Sum}'  number.txt
5050
[root@qls ~]# awk -F '[ ]'  '{Sum+=$1}END{print Sum}'  number.txt
5050

3. Awk的工作原理


[root@qls ~]# awk -F: '{print $1,$2}'  passwd

1. awk将文件中的每一行作为输入,并将每一行处理的时候放入到特定的模式空间中,将每一行的数据赋值给内部变量$0, 以换行符结束

2. awk开始进行字段分解,每个字段存储在自己的内部变量中, 变量从$1开始 

3. awk默认字段分割是由内部变量FS来指定的,可以使用-F修订,默认的分割符为空白字符

4. awk行处理时使用print来打印分割后的字段 

5. awk在打印之后会给不同的字段之间加上空格作为输出分隔符,这个分割符是由书写的逗号进行映射,逗号被映射到内部变量输出分隔符OFS,默认输出分隔符就是空格 #逗号映射输出分隔符,没有指定输出分隔符,那么默认就是空白字符。

6. awk输出之后,将从文件中读取下一行内容,并将其存储到$0变量中,覆盖原来的内容,然后接着进行循环处理,直到文件行处理结束

4. Awk命令格式


匹配的模式 

# /root/  就是匹配的模式   pattern     或者条件  

[root@qls ~]# awk '/root/'  passwd 
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

# '{print $1}'  动作  action  

[root@qls ~]# awk  -F: '{print $1}' passwd
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator

#模式+动作 

[root@qls ~]# awk  -F: '/root/{print $1}' passwd
root
operator

[root@qls ~]# df | awk '/\/$/{if ($3>2000000)print $4}'
47392452

5. Awk内部变量


#1. 输入分隔符   FS

#使用默认输入分隔符   默认分隔符为空白字符
[root@qls ~]# awk '{print $1}'  /etc/hosts
127.0.0.1
::1

#指定分隔符
[root@qls ~]# awk -F: '{print $1}'  passwd 
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator

[root@qls ~]# awk 'BEGIN{FS=":"}{print $1}'  passwd 
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator


#指定多个分隔符  

[root@qls ~]# ip a s eth0 | awk -F '[ /]*' 'NR==3{print $3}'  #通过正则匹配,将多个空格;视为一个分隔符
10.0.0.81

[root@qls ~]# ip a s eth0 | awk  'BEGIN{FS="[ /]*"}NR==3{print $3}'
10.0.0.81

#2. 输出分隔符  OFS

输出分隔符默认为空格  使用逗号进行映射  

[root@qls ~]# awk 'BEGIN{FS=":";OFS="@"}{print $1,$2}'  passwd 
root@x
bin@x
daemon@x
adm@x
lp@x
sync@x
shutdown@x
halt@x
mail@x
operator@x

# -v  使用内部变量  定义awk内部变量 
[root@qls ~]# awk  -F: -vOFS="$"  '{print $1,$2}'  passwd 
root$x
bin$x
daemon$x
adm$x
lp$x
sync$x
shutdown$x
halt$x
mail$x
operator$x

[root@qls ~]# awk  -vFS=":" -vOFS="$"  '{print $1,$2}'  passwd 
root$x
bin$x
daemon$x
adm$x
lp$x
sync$x
shutdown$x
halt$x
mail$x
operator$x

#3. 最后一列  NF  显示最后一列的编号,显示此行有多少列   $NF 打印最后一列 

[root@qls ~]# awk -F:  '{print NF,$NF}' passwd 
7 /bin/bash
7 /sbin/nologin
7 /sbin/nologin
7 /sbin/nologin
7 /sbin/nologin
7 /bin/sync
7 /sbin/shutdown
7 /sbin/halt
7 /sbin/nologin
7 /sbin/nologin

[root@qls ~]# awk -F:  '{print NF,$NF}' passwd  #每行不管有多少列,都是有最后一列的
6 /bin/bash
7 /sbin/nologin
7 /sbin/nologin
7 /sbin/nologin
7 /sbin/nologin
7 /bin/sync
7 /sbin/shutdown
7 /sbin/halt
7 /sbin/nologin
7 /sbin/nologin
[root@qls ~]# awk -F:  '{print $7}' passwd 		#没有第七列 

/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/bin/sync
/sbin/shutdown
/sbin/halt
/sbin/nologin
/sbin/nologin

#最后一列可以计算  
[root@qls ~]# awk -F:  '{print $(NF-1)}' passwd 
root
/bin
/sbin
/var/adm
/var/spool/lpd
/sbin
/sbin
/sbin
/var/spool/mail
/root

#4. 行号 NR  记录文件的行号或者编号  多个文件放在一起进行编号

[root@qls ~]# awk '{print NR,$0}' passwd 
1 root:x:0:0:root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8 halt:x:7:0:halt:/sbin:/sbin/halt
9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10 operator:x:11:0:operator:/root:/sbin/nologin

[root@qls ~]# awk 'NR==1' passwd 
root:x:0:0:root:/bin/bash
[root@qls ~]# awk 'NR<2' passwd
root:x:0:0:root:/bin/bash
[root@qls ~]# awk -F: 'NR==1{print $1}' passwd 
root

#5 行号 FNR  记录每个文件的行号或者编号 

[root@qls ~]# awk '{print NR,$0}' passwd   /etc/hosts
1 root:x:0:0:root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8 halt:x:7:0:halt:/sbin:/sbin/halt
9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10 operator:x:11:0:operator:/root:/sbin/nologin
11 127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
12 ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

[root@qls ~]# awk '{print FNR,$0}' passwd   /etc/hosts
1 root:x:0:0:root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8 halt:x:7:0:halt:/sbin:/sbin/halt
9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10 operator:x:11:0:operator:/root:/sbin/nologin
1 127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
2 ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6


#6. 格式化输出

#使用Awk的一种方式,自定义输出  
[root@qls ~]# date | awk '{print "今年是:"$NF"\t月份为:"$2}'
今年是:2020	月份为:May

#printf函数输出    了解   

[root@qls ~]# awk -F:  '{print "User: "$1,"UID: "$3,"GID: "$4}' passwd 
User: root UID: 0 GID: 0
User: bin UID: 1 GID: 1
User: daemon UID: 2 GID: 2
User: adm UID: 3 GID: 4
User: lp UID: 4 GID: 7
User: sync UID: 5 GID: 0
User: shutdown UID: 6 GID: 0
User: halt UID: 7 GID: 0
User: mail UID: 8 GID: 12
User: operator UID: 11 GID: 0

[root@qls ~]# awk -F:  '{printf "%-18s %-10s %-10s\n","User: "$1,"UID: "$3,"GID: "$4}' passwd 
User: root         UID: 0     GID: 0    
User: bin          UID: 1     GID: 1    
User: daemon       UID: 2     GID: 2    
User: adm          UID: 3     GID: 4    
User: lp           UID: 4     GID: 7    
User: sync         UID: 5     GID: 0    
User: shutdown     UID: 6     GID: 0    
User: halt         UID: 7     GID: 0    
User: mail         UID: 8     GID: 12   
User: operator     UID: 11    GID: 
#%-18s 是设置的第一列的最长字符长度,%-10s 第二列   %-10s 第三列  \n,使用printf要用\n进行输出换行否则就是这个样子:
awk -F:  '{printf "%-18s %-10s %-10s","User: "$1,"UID: "$3,"GID: "$4}' passwd 
User: root         UID: 0     GID: 0    User: bin          UID: 1     GID: 1    User: daemon       UID: 2     GID: 2    User: adm          UID: 3     GID: 4    User: lp           UID: 4     GID: 7    User: sync         UID: 5     GID: 0    User: shutdown     UID: 6     GID: 0    User: halt         UID: 7     GID: 0    User: mail         UID: 8     GID: 12   User: operator     UID: 11    GID: 0    [root@shell /service/scripts/day14]# 
#%s 字符类型  %d 数值类型  - 左对齐    printf 默认不自动换行 

[root@qls ~]# awk -F:  '{print "User: "$1,"UID: "$3,"GID: "$4}' passwd  | column -t
User:  root      UID:  0   GID:  0
User:  bin       UID:  1   GID:  1
User:  daemon    UID:  2   GID:  2
User:  adm       UID:  3   GID:  4
User:  lp        UID:  4   GID:  7
User:  sync      UID:  5   GID:  0
User:  shutdown  UID:  6   GID:  0
User:  halt      UID:  7   GID:  0
User:  mail      UID:  8   GID:  12
User:  operator  UID:  11  GID:  0

6. Awk模式动作


1. 正则表达式

[root@qls ~]# awk '/^root/'  passwd 
root:x:0:0:root:/bin/bash
[root@qls ~]# awk '/t$/'  passwd 
halt:x:7:0:halt:/sbin:/sbin/halt

[root@qls ~]# awk '!/n$/'  passwd 
root:x:0:0:root:/bin/bash
sync:x:5:0:sync:/sbin:/bin/sync
halt:x:7:0:halt:/sbin:/sbin/halt

[root@qls ~]# awk '$0 ~/^root/' passwd   #~ 类似于=~ 
root:x:0:0:root:/bin/bash
[root@qls ~]# awk -F: '$3 ~/0/' passwd 
root:x:0:0:root:/bin/bash

[root@qls ~]# awk -F: '$3 !~/0/' passwd  #!取反
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin

2. 比较表达式  

两个数值或者字符进行比较,只有条件为真时,才会执行指定的动作 

关系运算符 

<

>

<=

>=

==

!=

[root@qls ~]# awk -F: '$3==0' passwd 
root:x:0:0:root:/bin/bash
[root@qls ~]# awk -F: '$3==0{print $1}' passwd 
root

[root@qls ~]# awk -F: '$3<6{print $1,$3}' passwd 
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5

[root@qls ~]# awk -F: '$3>6{print $1,$3}' passwd 
halt 7
mail 8
operator 11


[root@qls ~]# awk -F: '$3>=6{print $1,$3}' passwd 
shutdown 6
halt 7
mail 8
operator 11
[root@qls ~]# awk -F: '$3<=6{print $1,$3}' passwd 
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6

[root@qls ~]# awk -F: '$3!=6{print $1,$3}' passwd 
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
halt 7
mail 8
operator 11

[root@qls ~]# awk -F: '$1 == "root" ' passwd 
root:x:0:0:root:/bin/bash

#双条件  并且
[root@qls ~]# awk -F: '$1 == "root" && $3 == 0 ' passwd 
root:x:0:0:root:/bin/bash

#或者
[root@qls ~]# awk -F: '$1 == "root" ||  $3 == 1 ' passwd 
root:x:0:0:root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin

[root@qls ~]# awk -F: '$1 != "root"' passwd 
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin


[root@qls ~]# awk -F: '$1 ~/^r/'  passwd 
root:x:0:0:root:/bin/bash
[root@qls ~]# awk -F: '$3 ~/^1/'  passwd 
bin:x:1:1:bin:/bin:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
[root@qls ~]# awk -F: '$3 ~/1$/'  passwd 
bin:x:1:1:bin:/bin:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin

[root@qls ~]# awk -F: '$3 !~/1$/'  passwd 
root:x:0:0:root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin


[root@qls ~]# df  | awk '/\/$/'
/dev/sda3       50101352 2709024  47392328   6% /
[root@qls ~]# df  | awk '/\/$/' | awk  '$3>2000000{print "磁盘根分区空间使用过多"}'
磁盘根分区空间使用过多
[root@qls ~]# df  | awk '/\/$/' | awk  '$3>3000000{print "磁盘根分区空间使用过多"}'
[root@qls ~]# 


#3. 条件表达式

[root@qls ~]# awk -F: '{if($3==0){print "管理员"$1}else{print "普通用户"$1}}' passwd 
管理员root
普通用户bin
普通用户daemon
普通用户adm
普通用户lp
普通用户sync
普通用户shutdown
普通用户halt
普通用户mail
普通用户operator

[root@qls ~]# awk -F: '{if($3==0){print "管理员"$1}}' passwd 
管理员root

[root@qls ~]# awk -F: '$3 == 0{print "管理员"$1}' passwd 
管理员root


#4. 运算表达式  
[root@qls ~]# awk 'BEGIN{print 1 + 1}'
2

[root@qls ~]# awk -F: '$3 + 10 >15' passwd 
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin

[root@qls ~]# awk -F: '/mail/{print $3}' passwd 
8
[root@qls ~]# awk -F: '/mail/{print $3 * 10 }' passwd 
80
[root@qls ~]# awk -F: '/mail/{print $3 + 10 }' passwd 
18
[root@qls ~]# awk -F: '/mail/{print $3 - 10 }' passwd 
-2
[root@qls ~]# awk -F: '/mail/{print $3 ^ 10 }' passwd 
1073741824

#5. 逻辑操作符  复合模式

&&  ||  !

[root@qls ~]# awk -F: '$1 == "root" && $3 == 0{print "管理员为:"$1}' passwd 
管理员为:root
[root@qls ~]# awk -F: '$1 == "root" || $3 == 1{print $1}' passwd 
root
bin

[root@qls ~]# awk -F: '$1 !~/^r/' passwd 
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin


[root@qls ~]# awk 'NR==1' passwd 
root:x:0:0:root:/bin/bash
[root@qls ~]# awk 'NR!=1' passwd 
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
[root@qls ~]# awk '/root/' passwd 
root:x:0:0:root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@qls ~]# awk '!/root/' passwd 
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin

#作业:解释下面命令的作用和含义

# awk '/west/' datafile    						取出包含west 的行
# awk '/^north/' datafile   					取出以north开头的行
# awk '$3 ~ /^north/' datafile 					取第三列以north开头的行
# awk '/^(no|so)/' datafile 					取以no或者so开头的行
# awk '{print $3,$2}' datafile  				打印第三,第二列中间以空白字符隔开
# awk '{print $3 $2}' datafile 					打印第三,第二列
# awk '{print $0}' datafile 					打印所有行的内容
# awk '{print "Number of fields: "NF}' datafile   打印每行的列数
# awk '/northeast/{print $3,$2}' datafile    	  打印包含字符串northeast的行的第3和第2列
# awk '/^[ns]/{print $1}' datafile  			打印以n或者s开头的行的第一列
# awk '$5 ~ /\. [7-9]+/' datafile 				打印第五列包含.789的行
# awk '$2 !~ /E/{print $1,$2}' datafile 		打印第二列不包含字符E的行的第一第二列
# awk '$3 ~ /^Joel/{print $3 "is a nice boy."}' datafile   打印第三列不是以joe开头的行的第三列
# awk '$8 ~ /[0-9][0-9]$/{print $8}' datafile				打印第八列出现两次0-9结尾的行的第八列
# awk '$4 ~ /Chin$/{print "The price is $" $8 "."}' datafile  打印第四列以chin结尾的行的第八列
# awk '/Tj/{print $0}' datafile   							打印包含字符Tj的行
# awk -F: '{print "Number of fields: "NF}' /etc/passwd 			以:为分隔符打印文件的所有行的列数
# awk -F"[ :]" '{print NF}' /etc/passwd  以空格和:为分隔符,打印 所有行的列数

7. Awk的条件判断


if  表达式   动作

if  表达式   动作  else  动作

if  表达式   动作 else if  表达式   动作 else  动作 

#打印当前系统中管理员用户

[root@qls ~]# awk -F: '{if($3==0){print $1"为系统管理员用户"}}'  passwd
root为系统管理员用户
bin为系统管理员用户

#统计系统用户的数量

[root@qls ~]# awk -F: '{if($3>0){i++}}END{print "系统用户的数量为:"i}' /etc/passwd
系统用户的数量为:49

#统计普通用户的数量

[root@qls ~]#  awk -F: '{if($3>0 && $3<1000){i++}}END{print "系统用户的数量为:"i}' /etc/passwd
系统用户的数量为:26
[root@qls ~]#  awk -F: '{if($3>=1000){i++}}END{print "普通用户的数量为:"i}' /etc/passwd
普通用户的数量为:23


[root@qls ~]# awk -F: '{if($3>=1000 && $3 != 65534){i++}}END{print "普通用户的数量为:"i}' /etc/passwd
普通用户的数量为:22

[root@qls ~]# awk -F: '{if($3>0 && $3<1000 || $3 == 65534){i++}}END{print "系统用户的数量为:"i}' /etc/passwd
系统用户的数量为:27

#统计管理员用户和系统用户的数量  

[root@qls ~]# awk -F: '{if($3==0){i++}else{j++}}END{print "管理员数量为:"i,"系统用户数量为:"j}' /etc/passwd
管理员数量为:1 系统用户数量为:49

#统计管理员用户和系统用户的数量及普通用户的数量  

[root@qls ~]# awk -F: '{if($3==0){a++}else if($3>0 && $3<1000){b++}else{c++}}END{print "管理员数量为:"a,"系统用户数量为:"b,"普通用户数量为:"c}'  /etc/passwd
管理员数量为:1 系统用户数量为:26 普通用户数量为:23

8. Awk的循环语句


#for循环  

#1. 打印1-10的数字  

[root@qls ~]# awk 'BEGIN{for (i=1;i<=10;i++){print i}}'
1
2
3
4
5
6
7
8
9
10

#2. 创建10个用户

[root@qls ~]# awk 'BEGIN{for (i=1;i<=10;i++){print "useradd qls"i}}' | bash

#3. 创建10个不同日期的文件  

[root@qls ~]# awk 'BEGIN{for (i=1;i<=10;i++){print "date -s 2020/05/"i" &>/dev/null && touch /tmp/file-"i".txt"}}'  | bash


#while  循环 

#1. 打印1-10的数字  


[root@qls ~]# awk 'BEGIN{a=1;while(a<=10){print a;a++}}'
1
2
3
4
5
6
7
8
9
10

a=1 
while [ a -le 10 ]
do
	echo a 
	let a++
done

#2. 创建10个用户

[root@qls ~]# awk 'BEGIN{a=1;while(a<=10){print "useradd qls"a;a++}}' | bash

#3. 创建10个不同日期的文件 

[root@qls ~]# awk 'BEGIN{a=1;while(a<=10){print "date -s 2020/05/"a" &>/dev/null && touch /tmp/file-"a".txt";a++}}'  | bash

9. Awk数组


i++		#统计次数    i[$1]++

i+=		#求和        i+=$1

#1. 统计/etc/passwd文件中每一种shell的数量

			awk 				   shell关联数组
	
赋值:  Shells[$NF]++       ==   	 let  Shells[$NF]++

打印:	 for (i in Shells)  ==  	for i in ${!Shells[@]}

		Shells      ==     ${!Shells[@]}    
		
索引值	  Shells[i]   ==     ${Shells[$i]}


[root@qls ~]# awk -F: '{Shells[$NF]++}END{for(i in Shells){print "Shell: "i,"Count: "Shells[i]}}'  /etc/passwd
Shell: /bin/sync Count: 1
Shell: /bin/bash Count: 23
Shell: /sbin/nologin Count: 24
Shell: /sbin/halt Count: 1
Shell: /sbin/shutdown Count: 1


#2. 统计tcp11中状态  

[root@qls ~]# netstat  -ant | awk   'NR>2{State[$NF]++}END{for(i in State){print "State: "i,"Count: "State[i]}}'
State: LISTEN Count: 7
State: ESTABLISHED Count: 1

#3. 计算1-100之间的和  

[root@qls ~]# seq 100| awk '{Sum+=$1}END{print Sum}'
5050

[root@qls ~]# head -1 access.log 
101.4.60.63 - - [30/Sep/2019:03:11:52 +0800] "HEAD /wp-content/themes/QQ2.8/js/mousewheel.js?ver=1.0.0 HTTP/1.1" 401 0 "-" "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Mobile Safari/537.36" "-"



#4. 统计日志中的PV量  一条日志就等于一个PV


[root@qls ~]# wc -l access.log
37590 access.log

[root@qls ~]# awk '{i++}END{print i}' access.log
37590

[root@qls ~]# awk '{PV[$1]++}END{for (i in PV) {Sum+=PV[i]}{print Sum}}'  access.log
37590


#5. 统计访问最多的10个IP地址


[root@qls ~]# awk '{Ips[$1]++}END{for (i in Ips)print "IP地址为: "i,"访问次数为: "Ips[i]}'  access.log |sort -rnk4 | head | column -t
IP地址为:  139.226.172.217  访问次数为:  16033
IP地址为:  47.102.42.79     访问次数为:  1041
IP地址为:  180.95.238.82    访问次数为:  993
IP地址为:  113.140.249.33   访问次数为:  726
IP地址为:  223.166.74.124   访问次数为:  646
IP地址为:  112.87.125.55    访问次数为:  525
IP地址为:  182.138.163.167  访问次数为:  429
IP地址为:  112.87.125.53    访问次数为:  373
IP地址为:  223.166.74.198   访问次数为:  352
IP地址为:  182.138.158.169  访问次数为:  308

#6. 统计访问次数大于100次的IP地址

[root@qls ~]# awk '{Ips[$1]++}END{for (i in Ips){if(Ips[i]>100){print "访问次数大于100次的IP地址为: "i,"访问次数为: "Ips[i]}}}'  access.log |sort -rnk4 | column -t
访问次数大于100次的IP地址为:  139.226.172.217  访问次数为:  16033
访问次数大于100次的IP地址为:  47.102.42.79     访问次数为:  1041
访问次数大于100次的IP地址为:  180.95.238.82    访问次数为:  993
访问次数大于100次的IP地址为:  113.140.249.33   访问次数为:  726
访问次数大于100次的IP地址为:  223.166.74.124   访问次数为:  646
访问次数大于100次的IP地址为:  112.87.125.55    访问次数为:  525
访问次数大于100次的IP地址为:  182.138.163.167  访问次数为:  429
访问次数大于100次的IP地址为:  112.87.125.53    访问次数为:  373
访问次数大于100次的IP地址为:  223.166.74.198   访问次数为:  352
访问次数大于100次的IP地址为:  182.138.158.169  访问次数为:  308
访问次数大于100次的IP地址为:  117.136.8.136    访问次数为:  260
访问次数大于100次的IP地址为:  113.140.251.30   访问次数为:  245
访问次数大于100次的IP地址为:  116.235.209.131  访问次数为:  219
访问次数大于100次的IP地址为:  203.34.152.133   访问次数为:  201
访问次数大于100次的IP地址为:  183.192.9.208    访问次数为:  162
访问次数大于100次的IP地址为:  222.68.114.200   访问次数为:  160
访问次数大于100次的IP地址为:  101.86.185.116   访问次数为:  153
访问次数大于100次的IP地址为:  61.171.179.116   访问次数为:  140
访问次数大于100次的IP地址为:  223.64.230.30    访问次数为:  140
访问次数大于100次的IP地址为:  139.227.12.139   访问次数为:  132
访问次数大于100次的IP地址为:  220.112.121.208  访问次数为:  127
访问次数大于100次的IP地址为:  123.126.113.152  访问次数为:  112

[root@qls ~]# awk  '{Ips[$1]++}END{for (i in Ips){if (Ips[i]>100){print i,Ips[i]}}}' access.log  | sort -rnk2 | column -t
139.226.172.217  16033
47.102.42.79     1041
180.95.238.82    993
113.140.249.33   726
223.166.74.124   646
112.87.125.55    525
182.138.163.167  429
112.87.125.53    373
223.166.74.198   352
182.138.158.169  308
117.136.8.136    260
113.140.251.30   245
116.235.209.131  219
203.34.152.133   201
183.192.9.208    162
222.68.114.200   160
101.86.185.116   153
61.171.179.116   140
223.64.230.30    140
139.227.12.139   132
220.112.121.208  127
123.126.113.152  112

#7. 统计访问最多的10个URL页面  $11 
awk '{Url[$11]++}END{for(i in Url){print "访问的Url:"i,"Count:"Url[i]}}' access.log |sort -rnk4


#8. 统计每种状态码的数量  
awk '{State[$9]++}END{for(i in State){print "状态码:"i,"Count:"State[i]}}' access.log


#9. 统计所有IP请求访问响应数据总大小   $10  
每个ip访问的总大小:awk '{Ip[$1]++;Sum[$1]+=$10}END{for(i in Ip){print "IP:"i,"Sum:"Sum[i]}}' access.log 

所有访问的总大小:awk '{Sum+=$10}END{print Sum}' access.log

#10. 统计每个IP地址访问的状态码的数量 

[root@qls ~]# awk '{Ips_State["IP: "$1" State: "$9]++}END{for (i in Ips_State){print i,"Count: "Ips_State[i]}}' access.log  | grep 139.226.172.217
IP: 139.226.172.217 State: 200 Count: 14731
IP: 139.226.172.217 State: 206 Count: 88
IP: 139.226.172.217 State: 404 Count: 193
IP: 139.226.172.217 State: 499 Count: 99
IP: 139.226.172.217 State: 302 Count: 108
IP: 139.226.172.217 State: 304 Count: 805
IP: 139.226.172.217 State: 504 Count: 9


#11. 统计每个IP地址的服务端响应的总字节大小及次数   

[root@qls ~]# awk '{Ips[$1]++;Sum[$1]+=$10}END{for (i in Ips){print "IP: "i,"Count: "Ips[i],"Size: "Sum[i]}}' access.log  | sort -rnk4 | head | column -t
IP:  139.226.172.217  Count:  16033  Size:  749869585
IP:  47.102.42.79     Count:  1041   Size:  16462
IP:  180.95.238.82    Count:  993    Size:  154136
IP:  113.140.249.33   Count:  726    Size:  105270
IP:  223.166.74.124   Count:  646    Size:  93670
IP:  112.87.125.55    Count:  525    Size:  15640394
IP:  182.138.163.167  Count:  429    Size:  62205
IP:  112.87.125.53    Count:  373    Size:  10792077
IP:  223.166.74.198   Count:  352    Size:  61217
IP:  182.138.158.169  Count:  308    Size:  44660

#12. 统计每个IP地址访问URL页面的服务端响应的总字节大小及次数
awk '{Ip_Url["ip:"$1 "url:"$11]++;Sum["ip:"$1 "url:"$11]+=$10}END{for (i in Ip_Url){print "IP: "i,"Count: "Ip_Url[i],"size: "Sum[i]}}' access.log



#13. 统计状态码为200的次数  
 awk '{State[$9]++}END{print "State: "200,"Count: "State[200]}' access.log 

posted @   zbzSH  阅读(37)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示