1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
awk 博大精深,本文仅持续更新在工作中频繁使用的方法。
 
 
 
【AWK】
使用逻辑判断  if  else
在逻辑处理过程中调用外部指令,并使用 getline 得到输出,最终赋值给变量
#!/bin/bash
#
# 2017/11/9
# decode etcdv3 output k/v with base64
 
### "key": "foo",
### "value": "bar",
 
ETCDCTL_API=3 etcdctl get -w json --prefix  '/'  |jq  '.'  | awk  -F '"'  '{
     if  ($2== "key" ) {
         "base64 -d<<< \"" $4 "\""  |getline $4
         print $1 "\"" $2 "\"" $3 "\"" $4 "\"" $5
     else  if  ($2== "value" ) {
         "base64 -d<<< \"" $4 "\""  |getline s_decode
         if  (index(s_decode,  "{" ) != 0) {
             print $1 "\"" $2 "\"" $3s_decode$5
         else  {
             print $0
         }
     else  {
         print $0
     }
}'
 
 
在处理数据前,先赋值几个变量
awk  - v  dt_a=` date  +%s` - v  dt_b=` date  +%s`  'BEGIN{if(dt_a==dt_b) {print 1} else {print 0}}'
 
 
 
截取一行数据中指定的2个数字做加减乘除运算:
请仔细对比下述3种方式的差异
[root@tvm01 asset] # echo 'aaa 1%, bbb 2%, ccc 3%, ddd 4%' |sed -r 's/.*([0-9]).*([0-9]).*([0-9]).*([0-9]).*/\1+\2/' |bc
3
[root@tvm01 asset] # echo 'aaa 1%, bbb 2%, ccc 3%, ddd 4%' |awk -F'%,' '{print $1$2}' |sed 's/[a-z]//g' |awk '{print $1+$2}'
3
[root@tvm01 asset] # echo 'aaa 1%, bbb 2%, ccc 3%, ddd 4%' |awk -F'[ %,]' '{print $2+$6}'                                   
3
 
 
去掉空格:
awk  '{ result=gensub(/ /,"",1);print result }'
 
打印某一段内容:
awk  '{print $7}'  access.log
 
统计IP数量:
awk  '{cs[$1]+=1} END {for(c in cs) print cs[c], c}'  access.log | sort  -nr
 
打印最后一列:
awk  '{print $8 " " $NF} '  access.log
 
统计大小:
awk  '{print $10 "  " $1 "  " $7}'  access.log| awk  '{B+=$1} END {print B/1024/1024 " MB"}'
 
统计TCP状态:
netstat  -n |  awk  '/^tcp/ {++state[$NF]} END {for(key in state) print key,"\t",state[key]}'
 
统计日志中http状态码:
zcat 2013-07-15-0000-2330_test.company.com.*| awk  '{print $9}' | sort | uniq  -c| sort  -nr| more
 
统计日志格式最后一行是源站IP的对应数据:
zcat 2013-07-15-*| awk  '$7~/test.company.com/{print $NF}' | sort | uniq  -c| sort  -nr| head
 
统计日志中第2行超过1M大小的URL,并打印第2行的大小和第3行的URL
awk  '$2~/.*M/ {print $2"\t"$3}'  access.log
 
统计日志中18点访问 test .company.com,状态码为200的数据,打印响应时间和源站地址:
zcat 2013-07-15-18*| grep  test .company.com| awk  '$9=="200"{print $(NF-7),$NF}' | sort | uniq  -c| sort  -nr| more
 
统计延时超过100ms的请求:
zcat 2013-07-15-18*| grep  test .company.com| awk  '$9=="0"&&$(NF-7)>100 {print $(NF-7)}' | sort | uniq  -c| sort  -nr| more
 
NR:整个脚本当前已经读过的记录数,就是行号,从1开始。随着所读文件的数目,一直累加。
FNR:同NR,不过是相对于当前在读的文件记录数。每开始读一个文件时,从1开始累加,相当于行号。读完一个文件后就会清0,新的文件又会从1开始。
http: //in .sdo.com/?p=1054
 
统计http code为502的数量,IP
假设有以下文件:
cs.502 : 统计了出现502的次数和IP,格式为“次数  IP”
cs.502.ip : 从cs.502中筛选出IP,格式为“IP”
cs.502.country : 利用qqwry做IP到地理位置的转换,格式为“IP  地理位置”
现在的需求是,把cs.502和cs.502.country合并
 
awk  'NR==FNR {a[$2]=$0;next} NR>FNR {print a[$1] " "$2}'  cs.502 cs.502.country >cs.502.log
 
计算http code 海外相对全部的占比是多少
test .all 的内容是:
46255 0
967 504
218 502
 
test .oversea 的内容是:
1171 0
408 504
205 502
 
awk  'NR==FNR {a[$2]=$1;next} NR>FNR {printf "%.2f% ", $1/a[$2]*100;print $2}'  test .all  test .oversea 
2.53% 0
42.19% 504
94.04% 502
 
计算百分比:
echo  55 4001638 | awk  '{printf "%.4f%\n",$1/$2*100}'
 
根据后3位来排序:
1231234214329049203
4239049230492039402
3209402394023940234
awk  '{print $0,substr($0,length($0)-2,3)}'  x.txt | sort  -n -k 2 |  awk  '{print $1}'
sed  -r  's/(.*)((.){3})/\1|\2/'  test .txt | sort  -n -k 2 -t \| | sed  's/|//g'
 
 
去重 
awk  '!a[$1]++'  test .log
 
展示 df 的简单版本,只显示磁盘分区和对应的used的值:
df  -h | sed  '1d'  | egrep  - v  "" /dev/shm "|" /dev/mapper ""  | awk  '{print $NF"\t"$(NF-1)}'  | while  read  a b;  do  echo  "$a used: $b" done
 
统计swap占用的进程:
for  in  ` cd  /proc ; ls  | grep  "^[0-9]" | awk  ' $0 >100' ` ; do  awk  '/Swap:/{a=a+$2}END{print ' "$i" ',a/1024"M"}'  /proc/ $i /smaps  ; done  | sort  -k2nr | head
 
统计最小值,使用 BEGIN 来初始化变量, if 做循环判断,END输出结果
test .log:
96.3738
95.72002499999999
96.78004999999999
95.8748
96.146125
96.7587
96.11826666666666
96.69625
95.88227499999999
96.4341
 
 
# cat test.log |awk 'BEGIN {min=100} {if ($1<min) {min=$1;x=$1}} END {print x}'
95.72002499999999
 
统计服务器的cpu,内存和磁盘信息,截取小数点,四舍五入
echo  ` hostname ` | cut  -d '.'  -f1 \
&&  echo  ` cat  /proc/cpuinfo  | grep  processor | wc  -l` 'C'  | tr  '\n'  '|'  \
&&  cat  /proc/meminfo  | grep  'MemTotal'  | awk  '{m=$(NF-1)/1024/1024;print m"G"}'  | tr  '\n'  '|'  \
&& lsblk -o SIZE,TYPE,MOUNTPOINT | grep  -E  '(data|disk1)'  | awk  '{print $1}'  \
&&  echo  && lsblk -o SIZE,TYPE,MOUNTPOINT &&  free  -m | grep  Mem | awk  '{print "Mem="$2"M"}'
 
 
 
参考
1、Getline 
https: //www .gnu.org /software/gawk/manual/html_node/Getline_002fVariable_002fPipe .html #Getline_002fVariable_002fPipe