作为一个大数据开拓,先来一个我比较喜好的口试题。
对付下面的nginx日志access.log,用脚本剖析出访问ip的Top 10。 实在这个题不难,但是稽核了几个常用的shell 命令,awk、uniq、sort、head,我以为对付做大数据开拓、运维、数仓等来说都是该当必备的。
2018-11-20T23:37:40+08:00119.15.90.30-"GET/free.php?proxy=out_hp&sort=&page=1HTTP/1.1""/free.php"-2000.1563626849/7213TLSv1.2ECDHE-RSA-AES128-GCM-SHA256---"Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.1;SV1;QQDownload732;.NET4.0C;.NET4.0E;LBBROWSER)"2018-11-20T23:37:44+08:00117.30.95.62-"GET/partner.phpHTTP/1.1""/partner.php"-2000.0164576534/6956TLSv1.2ECDHE-RSA-AES128-GCM-SHA256-https://blog.csdn.net/ithomer/article/details/6566739-"Mozilla/5.0(WindowsNT6.1;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/63.0.3239.132Safari/537.36"2018-11-20T23:37:44+08:00117.30.95.62-"GET/css/bootstrap.min.cssHTTP/1.1""/css/bootstrap.min.css"-2000.04539819402/19757TLSv1.2ECDHE-RSA-AES128-GCM-SHA256-https://proxy.mimvp.com/partner.php-"Mozilla/5.0(WindowsNT6.1;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/63.0.3239.132Safari/537.36"2018-11-20T23:37:44+08:00117.30.95.62-"GET/css/hint.min.cssHTTP/1.1""/css/hint.min.css"-2000.0003931635/1989TLSv1.2ECDHE-RSA-AES128-GCM-SHA256-https://proxy.mimvp.com/partner.php-"Mozilla/5.0(WindowsNT6.1;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/63.0.3239.132Safari/537.36"
来上答案

cataccess.log|awk'{print$2}'|uniq-c|sort-k1-nr|head-10
实在这个问题还有很多变种,比如除了脚本,用你最熟习的措辞写出来,还有如果文件过大,超过了内存限定,怎么处理。不过这些都是题外话了,我们今天主要讲一下awk在事情中的一些大略的运用。
实在awk的功能非常强大,不过本日我们紧张来讲讲在我们的事情中比较常用的awk用法。
awk'{[pattern]action}'{filenames}
切割文件
-F 指定拆分文件的分隔符,默认是空格或者 \t 比如上面的日志我们想获取第二列的ip地址,我们可以这样写
awk-F'''{print$2}'access.log
空格我们是可以不用写的,我这里写出来做一个示范。
实在还有一种分外字符,比如hive中默认分隔符是0x01,这种的利用awk怎么写呢?
awk-F'\\001''{print$1}'abcd.txt
内置变量的利用$n 由参数指定的分隔符切割之后,n用于打印出来第几个字段,索引从1开始。$0 用于打印出整行的字段.NF 每行数据切分之后,有多少列,比如我们可以用print $NF 来打印出末了一列
有一些时候我们可以用awk 截取个中的某几个字段拼接出来我们想要的一些语句。 比如我们想截取上面access.log里面的ip字段,然后天生一些sql,插入到数据库。
awk'{print"insertintomytable(ip)values('\''"$2"'\'');"}'access.log>/tmp/ip.sql
有人会问,这种场景一样平常什么时候会用呢,比如你有一万条或者更多的数据,你完备可以写一个sql来插入,但是如果是数量太多的话,一次性写入太多数据,会导致锁表,这个时候其他人就没法插入了,如果是线上的生产环境就更不许可了,以是对付一些类似的操作,我们可以拆分出多个sql来一个个的实行,这样单个sql锁表的韶光就会减少,避免永劫光锁表带来的数据库不可用。
正则匹配有时候我们只想打印出来一些我们想要的列,我们可以通过正则匹配来做。
比如我们想打印出来上面的access.log中117开头的ip,可以这样做.
awk'$2~/^117/{print$2}'access.log
类sql功能
实在awk还可以帮我们实现一些大略的类似sql的功能,我们也大略说一下。
比如我们有一个下面的学生表
id 班级 姓名
id class name
1 1班 张三
2 2班 李四
3 1班 王五
4 3班 赵六
比如我们想统计每个班级有多少同学,可以利用如下命令
awk'{a[$2]++}END{for(iina){printi"人数:"a[i]}}'student.txt
我们定义了一个类似map的变量a,key是班级名称,也便是第二列,value值是每个班级对应的人数,末了通过一个for循环输出。
实在awk还有非常多、非常强大的功能,但是对付我们事情中我以为用途并不大,这里就不着重先容了,感兴趣的朋友可以网上找一些干系的资料。
更多精彩内容,欢迎关注我的"大众年夜众号[大数据技能与运用实战],一起发展.