awk数组
awk数组
1.什么是awk数组
数组其实也算是变量,传统的变量只能存储一个值,但数组可以存储多个值
2.awk数组应用场景
通常用来统计、比如:统计网站访问TOP10、网站url访问TOP10等等
3.awk数组统计技巧
1.在awk中,使用数组时,不仅可以使用123...n作为数组索引,也可以使用字符串作为数组索引。
2.要统计某个字段的值,就将该字段作为数组的索引,然后对索引进行遍历。
4.awk数组的语法
array_name[index]=value
awk数组示例
例:统计passwd文件中,各种shell类型的个数
以:为分隔符,第7列就是shell类型,可用7表示,或用NF表示
BEGIN{
FS=":"
}
{ #赋值操作
sh[$NF]++ #如果出现相同类型shell就让其加1,出现不同类型的shell就新存一个数组
}
END{ #赋值完成后,需要通过循环的方式将其索引的次数遍历出来
for (item in sh){
print item,sh[item]
}
}
Nginx日志分析
日志格式如下:
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
52.55.21.59 - - [25/Jan/2018:14:55:36 +0800] "GET /feed/ HTTP/1.1" 404 162 "https://www.google.com/" "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; de) Presto/2.9.168 Version/11.52" "-"
这里随便找了个日志进行测试,所以日志量不够,将就看吧
1.统计访问最多的10个IP
awk '{accessip[$1]++} END{for(item in accessip){printf "%-20s %-20s \n",accessip[item],item}}' access.log |sort -nr|head -10
或
{
accessip[$1]++ #统计每个IP出现的次数,出现相同的IP 就自增,不同的IP就存到新的数组
}
END{
for(item in accessip){
print accessip[item],item #accessip[item]对应一个IP出现的次数,item表示IP地址,也就是数组的索引
}
}
这里的sort 命令用于排序,-n:按照数值大小进行排序,-r以相反的顺序来排序
2.统计访问大于100次的IP
在之前的基础上加一个判断,判断IP的访问量是否大于100,大于就打印
awk '{accessip[$1]++} END{for(item in accessip){if(accessip[item]>100){ printf "%-20s %-20s \n",accessip[item],item}}}' access.log |sort -nr
或
{ #统计每个IP出现的次数
accessip[$1]++
}
END{ #accessip[item]对应一个IP出现的次数,item表示IP地址,也就是数组的索引
for(item in accessip){
if(accessip[item]>100){
printf "%-20s %-20s \n",accessip[item],item
}
}
}
3.统计访问最多的10个页面($request top 10)
第7列是请求到的内容
awk '{req[$7]++}END{for(item in req){print req[item],item}}' access.log |sort -rn|head -10
或
{
req[$7]++
}
END{
for(item in req){
print req[item],item
}
}
4.统计每个IP访问状态码数量($status)
第九列是状态码
awk '{ip_status[$1 "" $9]++}END{for(item in ip_status){print ip_status[item],item}}' access.log
或
{
ip_status[$1" "$9]++
}
END{
for(item in ip_status){
print ip_status[item],item
}
}
5.统计访问状态码为404及出现的次数($status)
在之前的基础上,对状态码进行判断,等于404就打印
awk '{ip_status[$9]++}END{for(item in ip_status){if(item==404){print ip_status[item],"次",item}}}' access.log
或
{
ip_status[$9]++
}
END{
for( item in ip_status){
if(item==404){
print ip_status[item],"次",item
}
}
}
6.统计每个URL访问内容总大小
{
url[$7]+=$10
}
END{
for (item in url){
print url[item],item
}
}
{
url[$7]+=$10
}
END{
for (item in url){
if(url[item]/1024/1024 >0) {
print url[item]/1024/1024"Mb",item
}
}
}
{
url[$7]+=$10
cont[$7]++
}
END{
for (item in url){
if(url[item]/1024/1024 >0) {
print url[item]/1024/1024"Mb",item,cont[item],"次"
}
}
}
统计各种状态码出现的数量
awk '{code[$9]++} END {for(i in code){print i,code[i],"次"}}' acccess.log
{
if($9>=100 && $9<200) {
i++
}
else if ($9>=200 && $9<300) {
j++
}
else if ($9>=300 && $9<400) {
k++
}
else if ($9>=400 && $9<500) {
n++
}
else if($9>=500) {
p++
}
}
END{print i,j,k,n,p,i+j+k+n+p
}