awk常用命令
Contents
基础说明
基本用于简单统计各种log数据,特别是access log
以解析腾讯cdn的access log格式为例
另外awk要全面学好不容易,这里只是简单涉及一些常用语法
log字段含义
- $4=url
- $5=字节数大小
- $10=request_time(毫秒)
cdn字段详细解析
基本语法
awk -F|-f|-v ‘BEGIN{ } / / {comand1;comand2} END{ }’ file
- -F 定义列分隔符
- -f 指定调用脚本
- -v 定义变量
- ‘ ‘引用代码块,awk执行语句必须包含在内
- BEGIN{ } 初始化代码块,在对每一行进行处理之前,初始化代码,主要是引用全局变量,设置FS分隔符
- { } 命令代码块,包含一条或多条命令
- // 用来定义需要匹配的模式(字符串或者正则表达式),对满足匹配模式的行进行上条代码块的操作
- END{ } 结尾代码块,在对每一行进行处理之后再执行的代码块,主要是进行最终计算或输出结尾摘要信息
特殊符号
符号 | 含义 |
---|---|
$0 | 表示整个当前行 |
$1 | 每行第一个字段 |
NF | 字段数量变量,$NF就是最后一列 |
NR | 每行的记录号,多文件记录递增 |
FNR | 与NR类似,不过多文件记录不递增,每个文件都从1开始 |
\t | 制表符 |
\n | 换行符 |
FS | BEGIN时定义分隔符 |
RS | 输入的记录分隔符, 默认为换行符(即文本是按一行一行输入) |
~ | 匹配,与==相比不是精确比较 |
!~ | 不匹配,不精确比较 |
== | 等于,必须全部相等,精确比较 |
!= | 不等于,精确比较 |
&& | 逻辑与 |
|| | 逻辑或 |
+ | 匹配时表示1个或1个以上 |
/[0-9][0-9]+/ | 两个或两个以上数字 |
/[0-9][0-9]*/ | 一个或一个以上数字 |
FILENAME | 文件名 |
OFS | 输出字段分隔符, 默认也是空格,可以改为制表符等 |
ORS | 输出的记录分隔符,默认为换行符,即处理结果也是一行一行输出到屏幕 |
-F’[:#/]’ | 定义三个分隔符 |
常用命令
慢url
request time > 500ms 的url
1 | awk '($10>500){split($4,a,"?");print $1,a[1],$10}' 30a.txt |
语法知识
split($4,a,”?”) 使用?分割后存放在数组a
筛选url
筛选包含base关键字的url
1 | awk '/base/{if($10>500){split($4,a,"?");print $1,a[1],$10}}' 30a.txt |
语法知识
/正则/ 筛选的内容
$5~/base/ ,第5列匹配base
根据url分组求和(每个url消耗流量)
1 | cat 30a.txt |awk '{split($4,a,"?"); x[a[1]] += $5}END{for(i in x){print i, x[i]}}'|sort -k2 -n |
语法知识
x[a[1]] += $5 ,x数组使用a[1]作为下标累加流量值($5)
for(i in x){print i, x[i]}, for i循环获取x数组下标并打印
END, END前代码处理完所有行,再用END后代码打印
sort -k2 ,按第二列排序
url平均耗时
1 | gawk -F, 'NF == 3 { sum[$2] += $3; N[$2]++ } |
语法知识
N[$2]++, 自增
avg = sum[key] / N[key], 计算平均值 = 总数/次数
url访问次数排序
1 | cat 30a.txt |awk '{split($4,a,"?"); u=a[1]; N[u]++} END {for(i in N){print i, N[i]}}' | sort -k2 -n |
去重
根据第二排去重输出
1 | awk '!a[$2]++ {print $2,$3}' a.txt |
语法知识
awk和python一样参数空或0为false,非空或非零为true
使用$2为下标自增后,第一次是0,!反转后为true,之后都是false,所以只有第一次遇到会通过判断
分区统计
统计区间内数量
1 | awk -F, 'BEGIN{a=0;b=0;c=0;d=0;e=0}{if($2<50000000)a+=1;else if($2>=50000000 && $2<100000000) b+=1; else if($2>=100000000 && $2 < 200000000) c+=1; else if($2 >= 200000000 && $2 <500000000)d+=1; else e+=1}END{print a,b,c,d,e}' |
统计区间占比
1 | awk -F, 'BEGIN{a=0;b=0;c=0;d=0;e=0}{if($2<50000000)a+=$2;else if($2>=50000000 && $2<100000000) b+=$2; else if($2>=100000000 && $2 < 200000000) c+=$2; else if($2 >= 200000000 && $2 <500000000)d+=$2; else e+=$2}END{sum=a+b+c+d+e;print a/sum,b/sum,c/sum,d/sum,e/sum}' |