awk按列求和求平均值、locate: command not found问题、awk统计搜索包含多个关键符号的行数命令以及awk对nginx的日志按接口统计的实现

 一、用awk实现按列求和求平均值

   平常在服务器运维处理的过程中,肯定会要对日志进行一些处理,比如日志统计中肯定需要用上对取出来的一列数据进行求和求平均值。使用awk很容易实现。具体演示的命令如下:

[root@123 build]# ll
total 336
-rw-rw-r-- 1 1000 1000   3330 Mar 14 21:17 ax_check_compile_flag.m4
-rw-rw-r-- 1 1000 1000   2200 Mar 14 21:17 build2.mk
-rwxrwxr-x 1 1000 1000   2165 Mar 14 21:17 buildcheck.sh
-rw-rw-r-- 1 1000 1000   2510 Mar 14 21:17 build.mk
-rwxrwxr-x 1 1000 1000    381 Mar 14 21:17 config-stubs
-rw-rw-r-- 1 1000 1000    700 Mar 14 21:17 genif.sh
-rw-rw-r-- 1 1000 1000 230377 Mar 14 21:17 libtool.m4
-rw-rw-r-- 1 1000 1000   2225 Mar 14 21:17 mkdep.awk
-rw-rw-r-- 1 1000 1000   1556 Mar 14 21:17 order_by_dep.awk
-rw-rw-r-- 1 1000 1000    122 Mar 14 21:17 print_include.awk
-rw-rw-r-- 1 1000 1000    410 Mar 14 21:17 scan_makefile_in.awk
-rwxrwxr-x 1 1000 1000  65761 Mar 14 21:17 shtool
[root@123 build]# ll | awk '{print $5}'
3330
2200
2165
2510
381
700
230377
2225
1556
122
410
65761
[root@123 build]# ll | awk '{a=a+$5;b++;}END{print a,b,a/b}'
311737 13 23979.8
[root@123 build]# ll | awk '/build/ {print $9,$5}'                  
build2.mk 2200
buildcheck.sh 2165
build.mk 2510
[root@123 build]# ll | awk '/build/ {a=a+$5;b++}END{print a,b,a/b}' 
6875 3 2291.67
[root@123 build]# 

二、locate: command not found问题的解决

     在linux的使用中,locate是经常用到的查找命令,因为它是基于文件索引数据库进行查找,速度非常快。

    但是有时在某台服务器上执行locate查找时却提示locate: command not found.这一看原因当然是未安装locate,然而当使用yum install -y locate却发现结果非常沮丧,不要担心,只是玩了个文字游戏,安装包名并不是locate,而是mlocate.所以使用yum install -y mlocate安装后即可使用locate.

[root@123 kermit]# locate php.ini
-bash: locate: command not found
[root@123 kermit]yum install -y mlocate
Installed:
  mlocate.x86_64 0:0.22.2-6.el6                                                                                                                                                 
Complete!
[root@123 kermit]# locate php.ini             
locate: can not stat () `/var/lib/mlocate/mlocate.db': No such file or directory
[root@123 kermit]# updatedb
[root@123 kermit]# locate php.ini
/opt/download/php-7.1.3/php.ini-development
/opt/download/php-7.1.3/php.ini-production
/opt/modules/php7/etc/php.ini
[root@123 kermit]# 

    关于查找之前一篇文章,关于locate,mlocate,slocate的,linux上的文件查找locate-slocate-mlocate:可以搜索: linux上的文件查找locate-slocate-mlocate

三、awk统计搜索包含多个关键符号的行数命令

简单的行数统计命令,wc-l就足够了。

如果要统计搜索包含某个关键字符的行数:

 grep -c '203.208.60.214' 201610.log #统计某个IP出现的行数

当然也可以这样:

grep  '203.208.60.214' 201610.log | wc -l #先搜索出符合条件的结果再计算行数

grep -c 只能针对一个关键词,针对两个关键词就不能简单这样用了,需要用正则表达式。这里使用awk命令,使用awk实现搜索的命令示例如下,注意点号前要加反斜线

awk '/203.208.60.214/{print $0}' 201610.log  | wc -l

当然也可以使用awk统计行数:

awk '/203.208.60.214/{print $0}' 201610.log | awk 'END{print NR}'

 当要搜索多个关键词时,这时就需要使用awk的通配符了。

shell基础正则表达式:
*      前一个字符匹配0次或任意多次
.      匹配除了换行符外任意一个字符
^      匹配行首。^abc 即 匹配以abc开头的行
$      匹配行尾。abc$ 即 匹配以abc结尾的行
[]      匹配中括号中指定的任意一个字符,只匹配一个字符。[aeiou]匹配任意一个元音字母,[0-9][a-z]匹配小写字母和一位数字构成的两位字符
[^]     匹配除中括号内的字符以外的任意一个字符
       转义符。用于将特殊符号的含义取消
{n}    匹配其前面的字符恰好出现n次。[0-9]{2} 匹4位数字
{n,}    匹配其前面的字符出现不小于n次。
{n,m}    匹配其前面的字符至少出现n次,最多出现m次。[a-z]{6,8} 匹配6到8位的小写字母

使用awk搜索多个关键词的命令如下:

awk '/apk\.php.*from=baidu/{print $0}' log.log | wc -l 

四、awk对nginx的请求日志按接口进行统计

    服务器上的接口数量已经不知道有多少了,特别是一个长尾接口请求量不是很大的,想考虑对线上服务器进行一些接口迁移处理,于是着手对线上的请求日志进行统计,目标就是能统计出各个接口的请求数量,但是呢,因为系统的遗留问题,接口并不规范,各端(安卓和iphone以及ipad)的请求URL格式不一样,另外内部还有一大堆的无规则的rewrite处理,不好办。经过对请求日志的慢慢整理,今天基本统计出了一些核心的请求接口,同时也把所有的长尾请求接口也都列了出来。在此做个笔记, 

#awk对所有分离出来的uri请求进行分析保存,
sudo awk '{ \
	#awk对直接请求的.php接口,截取到.php即可
	if($0 ~ /.php/) print substr($0,0, index($0,".php")+3); \
	#awk对请求的.json格式,因为其之前会有数字被rewrite参数,截取到数字出现
	else if ($0 ~ /.json/) print substr($0,0,match($0,/[0-9]/)?(match($0,/[0-9]/)-1):100); \
	#awk对请求的图片,出现数字被rewrite,截取到数字出现
	else if ($0 ~ /.jpg|.gif|.png|.jpeg|.bmp/) print substr($0,0,match($0,/[0-9]/)-1); \
	#awk对固定的请求,直接统一
	else if ($0 ~ /^\/shell\//) print "/shell/" ; \
	else if ($0 ~ /\/k\/v1\//) print "/k/v1/"; \
	else if ($0 ~ /\/s\/v1\//) print "/s/v1/"; \
	else if ($0 ~ /\/favicon.ico/) print "/favicon.ico"; \
	#这是垃圾请求,为了好和总数比较,也输出
	else if ($0 ~ /^\/\(null\)/) print "/(null)"; \
	else if( $0 == "/") print $0 ;\
	#少许的直接静态请求分离出来
	else if( $0 ~ /.js$|.css$|.html$|.txt$/) ; \
	else print $0 \
}' url.log > validurl.log

#对上面的结果进行统计
sudo sort validurl.log | uniq -c | sort -nr -k 1 >> sort.log

     这样就把单台服务器上的请求接口统计出来了,整个请求的URL中哪些没有处理直接输出原样的也可通过下面的命令查看,同时发现不在这些请求里面的接口不多,且基本都是注入请求。

sudo awk '{ \
	if($0 ~ /.php/) ; \
	else if ($0 ~ /.json/) ; \
	else if ($0 ~ /.jpg|.gif|.png|.jpeg|.bmp/) ; \
	else if ($0 ~ /^\/shell\//) ; \
	else if ($0 ~ /\/k\/v1\//) ; \
	else if ($0 ~ /\/s\/v1\//) ; \
	else if ($0 ~ /\/favicon.ico/) ; \
	else if ($0 ~ /^\/\(null\)/) ; \
	else if( $0 == "/") ;\
	else if( $0 ~ /.js$|.css$|.html$|.txt$/) ; \
	else print $0 \
}' url.log

五、 awk对某项字符串split切开及提取部分内容

    在使用awk进行统计时候,突然有这样的需求,如下为一个文本集合,简化一下我最终的需求吧,我需要对这个文本中进行判断是否存在/**/**/这种格式,如果存在就提取/**/**/这个内容,后面的内容则不再需要,内容如下:

    这里的这行内容已经是在使用了awk进行提取的前提下得到的内容,所以不要简单想成直接使用awk进行操作,当然你先一步awk来提出来这些内容,再第二次用awk进行统计也可以实现我这简单描述的需求,但是如果前期处理比较复杂那就不适用了,开始我想到的是awk的index方法,但是index方法只返回是否找到字符而不会区分能查找到的次数。在我觉得不好办的时候,发现了split方法可以使用。如下:

[online@G18 ~ ~]$ cat t.log 
/ipad/cover/reums/hs/hello.php
/ipad/ssbum/kkk.test
/coer/lbum/iphone/regh/vs/ts.json
/ipad/channel/tv.com
/reqs/apkncent.php?username=yesmi
/covr/abu/iphone/regh/hs/?think
/sets/apt?k=name
[online@G18 ~ ~]$ awk '{print index($0, "/")}' t.log 
1
.....
[online@G18 ~ ~]$ awk '{if ($0 ~ /\/[^\/]*\/[^\/]*\//) {split($0,Array,"/"); print "/"Array[2]"/"Array[3]"/";} }' t.log 
/ipad/cover/
/ipad/ssbum/
/coer/lbum/
/ipad/channel/
/covr/abu/

    如上,在我觉得只能使用split方法的时候,我看到了match方法中的功能提示:(match( String, Ere ) 在String 参数指定的字符串(Ere 参数指定的扩展正则表达式出现在其中)中返回位置(字符形式),从 1 开始编号,或如果 Ere 参数不出现,则返回 0(零)。RSTART 特殊变量设置为返回值。RLENGTH 特殊变量设置为匹配的字符串的长度,或如果未找到任何匹配,则设置为 -1(负一)。 注意看:match中RLENGTH 特殊变量设置为匹配的字符串的长度,让我对match也充满了希望,经过测试这个也是可行的。经过多次调试得到了如下可行的办法:

[online@G18 ~ ~]$ awk '{if(s=match($0, /\/[^\/]*\/[^\/]*\//)) print s,RSTART,RLENGTH, substr($0, RSTART, RLENGTH);}' t.log  
1 1 12 /ipad/cover/
1 1 12 /ipad/ssbum/
1 1 11 /coer/lbum/
1 1 14 /ipad/channel/
1 1 10 /covr/abu/
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林戈的IT生涯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值