awk练习

统计相同列的和

案例一:
[root@MyFirstwon awk]# cat file
13393985	8
1093602796	1
13393985  	2
1093602796	9
[root@MyFirstwon awk]# awk '{s[$1]+=$2}END{for(i in s){print i,s[i]}}' file
13393985 10
1093602796 10
[root@localhost awk]# 
案例二:
[root@MyFirstwon awk]# cat file2 
13393985	T 8
1093602796	S 1
13393985	T 2
1093602796	R 9
[root@MyFirstwon awk]# awk '{s[$1" "$2]+=$3}END{for(i in s){print i,s[i]}}' file2 |column -t
1093602796  R  9
1093602796  S  1
13393985    T  10
[root@MyFirstwon awk]# awk '{s[$1,$2]+=$3}END{for(i in s){print i,s[i]}}' file2 |column -t
13393985 T   10
1093602796 R   9
1093602796 S   1
[root@MyFirstwon awk]# 
awk 案例

场景:

[root@MyFirstwon awk]# cat file5 
13393985		8
1093602795		1


[root@MyFirstwon awk]# cat file6 
13393985		8	31
1093602796		1	22
13393985		2	19
1093602796		9	28
1111111111		44	33
22222222		6	55
[root@MyFirstwon awk]# 

需求1:
以第一列 为变量名  第一列为变量,将相同第一列的第二列数据进行累加打印出和.

[root@MyFirstwon awk]# awk '{s[$1]+=$2}END{for(i in s)print i,s[i]}' file5 file6 |column -t
13393985    18
1093602795  1
1111111111  44
1093602796  10
22222222    6
[root@MyFirstwon awk]# 

需求2:
以第一列和第二列为变量名, 将相同第一列、第二列的第三列数据进行累加打印出和
[root@MyFirstwon awk]# cat file2 
13393985	T 8
1093602796	S 1
13393985	T 2
1093602796	R 9

[root@MyFirstwon awk]# awk '{s[$1"  "$2]+=$3}END{for(i in s)print i,s[i]}' file2 |column -t
1093602796  R  9
1093602796  S  1
13393985    T  10
[root@MyFirstwon awk]# 

需求3:
如果第一列相同,则根据第一列来分组,分别打印第二列和第三列的和
[root@MyFirstwon awk]# cat file3 
13393985	31	8
1093602796	22	1
13393985	19	2
1093602796	28	9

[root@MyFirstwon awk]# awk '{a[$1]+=$2;b[$1]+=$3}END{for(i in a){print i,a[i],b[i]}}' file3 
13393985 50 10
1093602796 50 10
[root@MyFirstwon awk]# 

需求4: 求交集
如果file5、file6中,2个文件的第一列值相同,输出第2个文件的所有列
[root@MyFirstwon awk]# awk 'NR==FNR{s[$1]=1}NR>FNR&&s[$1]>0{print $0}' file5 file6 
13393985		8	31
13393985		2	19
[root@MyFirstwon awk]# 
需求5: 集合差
针对2个文件的第一列做比较,输出:在file2中去除file1中第一列出现过的行
[root@MyFirstwon awk]# awk 'NR==FNR{s[$1]=1}NR>FNR&&s[$1]<1 {print $0}' file5 file6 
1093602796		1	22
1093602796		9	28
1111111111		44	33
22222222		6	55
[root@MyFirstwon awk]# 

需求6: 匹配非交集
如果file5、file6中,2个文件的第一列值相同,输出第2个文件的所有列
[root@MyFirstwon awk]# awk 'NR==FNR{s[$1" "$2]=1}NR>FNR&&s[$1" "$2]>0{print $0}' file5 file6 
13393985		8	31
[root@MyFirstwon awk]# 
案例三: 统计access.log文件中每个ip地址使用了多少流量
[root@MyFirstwon nginx]# awk '{count[$1]++;sum[$1]+=$10}END{for(i in sum)print "IP: "i,"次数: "count[i],"流量: "sum[i]}' access.log|sort -nrk4|column -t|head
IP:  23.100.232.233   次数:  69  流量:  526020
IP:  120.28.22.106    次数:  29  流量:  588936
IP:  218.56.104.42    次数:  25  流量:  242987
IP:  66.249.79.206    次数:  23  流量:  102702
IP:  66.249.79.208    次数:  11  流量:  82399
IP:  40.77.167.91     次数:  11  流量:  6806
IP:  27.33.46.54      次数:  8   流量:  722
IP:  66.249.79.210    次数:  6   流量:  33467
IP:  42.236.10.103    次数:  6   流量:  12955
IP:  176.9.51.93      次数:  6   流量:  22247
[root@MyFirstwon nginx]# 

[root@MyFirstwon ghost]# ss -an|awk 'BEGIN{print "State","Num","Recv-Q","Send-Q"}{++s[$2];a[$2]+=$3;b[$2]+=$4}END{for(i in s)print i,s[i],a[i],b[i]}'|column -t
State   Num  Recv-Q  Send-Q
LISTEN  18   0       1962
ESTAB   50   0       0
State   1    0       0
UNCONN  59   343040  0
[root@MyFirstwon ghost]# 

NR 和 FNR 的区别

对于NR,读取不同文件,NR是一直++的。

[root@MyFirstwon awk]# awk '{print NR,$0}' file file2 
1 13393985	8
2 1093602796	1
3 13393985  	2
4 1093602796	9
5 13393985	T 8
6 1093602796	S 1
7 13393985	T 2
8 1093602796	R 9
[root@localhost awk]#

对于FNR,读取不同文件,开始下一个文件的时候FNR又从1开始了

[root@MyFirstwon awk]# awk '{print FNR,$0}' file file2 
1 13393985	8
2 1093602796	1
3 13393985  	2
4 1093602796	9
1 13393985	T 8
2 1093602796	S 1
3 13393985	T 2
4 1093602796	R 9
[root@MyFirstwon awk]# 

三元运算符

[root@MyFirstwon test]# cat test 
22,44
33,11
15,51
[root@MyFirstwon test]# cat test |awk -F, '{max=$1>$2?$1:$2;print max}'
44
33
51
[root@MyFirstwon test]#
统计UID小于或等于500的用户个数
[root@localhost shell]# awk -F ':' 'BEGIN{i=1;j=1}{if($3<=500){i++}else{j++}}END{print i,j}' /etc/passwd
26 5
[root@localhost shell]# awk -F ':' 'BEGIN{i=1;j=1}{$3<=500?i++:j++}END{print i,j}' /etc/passwd
26 5
[root@localhost shell]# 
[root@MyFirstwon test]# seq 10 | awk '{s=s ? s";"$1 : $1}END{print s}'
1;2;3;4;5;6;7;8;9;10
[root@MyFirstwon test]#

RT 很少人使用 但贼强大

[root@MyFirstwon test]# cat /etc/redhat-release 
CentOS Linux release 7.4.1708 (Core) 
[root@MyFirstwon test]# awk -v RS='[0-9]+' '{print RT}' /etc/redhat-release 
7
4
1708
[root@MyFirstwon test]# awk -v RS='[0-9]+' 'NR==1{print RT}' /etc/redhat-release 
7
[root@MyFirstwon test]# 

三目运算累加不同单位

[root@MyFirstwon test]# cat 123 
75955M
13232K
17492K
75953M
75963M
2G
10G
5T
[root@MyFirstwon test]# awk '{a+=/T/?$0*1024:(/M/?$0/1024:(/K/?$0/(1024^2):$0))}END{print a"G"}' 123
5354.56G
[root@MyFirstwon test]# awk '{a+=/G/?$0/1024:(/M/?$0/(1024^2):(/K/?$0/(1024^3):$0))}END{print a"T"}' 123
5.22906T
[root@MyFirstwon test]# awk '{a+=/T/?$0*(1024^2):(/G/?$0*1024:(/K/?$0/1024:$0))}END{print a"M"}' 123
5.48307e+06M
[root@MyFirstwon test]# awk '{a+=/T/?$0*(1024^2):(/G/?$0*1024:(/K/?$0/1024:$0))}END{printf"%.fM\n",a}' 123
5483069M
[root@MyFirstwon test]#
comments powered by Disqus