场景
老板交代一个任务,处理一批数据,从文本找出攻击次数top 10的ip。你看了下,这个文本大小有980M,有831136条数据。 目前在我脑海里面,方式大致有三种,一是用excel,不懂计算机的人一般会想到这种方法,但是这么大的文件用excel打开,估计会卡死;二是导入数据库后用sql语句;三是使用linux命令,本篇文章将采用这种方式。
一条命令搞定
通过命令查看文本每行的数据格式
head -n 1 attact_log.csv
以逗号作为分割符,第一个值是IP,这个是我们要统计的。
最终可以通过以下命令完成统计
cat attack_log.csv |awk -F ',' '{print $1}' |sort |uniq -c |sort -k 1 -n -r |head -n 10
统计80多万条数据,接近1G的文件,处理时间大约1分钟左右,速度还是可以接受的。对这条命令进行详细讲解一下:
awk -F ',' '{print $1}'
是每行文本的第一列,-F参数表示列的分割符,这里文本是用逗号作为分割列的,如果不写默认是空格。$1表示第一列,这里要注意的是,不是从0开始计数的,0代表完整的一行,这与正则表达式group(0)类似。
sort从字面就可以看出来是排序的意思。之前我以为sort是按照ASCII码来排序的,后来发现不是,网友给的答案是'空字符串<空白字符<数值<a<A<b<B<...<z<Z'。 排序的目的是把相同的行集中在一起,这样才能使用后续的uniq -c命令,对邻近重复的行进行统计,并删除重复的行。结果行的第一列是个数,第二列是值。目前为止top的结果如图:
到了uniq这步以完成了每个ip的次数统计,但是没有按照次数降序排序。因此再次使用sort,其中参数-k 1代表以第一列值作为排序的依据;-n表示把第一列当作数字来对待,否则会出现2排在19前面的情况;sort默认是按照升序,-r是让其降序。最后通过head -n 10只显示top 10。
在使用awk命令时,还可添加判断条件,比如要取某列大于10的列,可写成
awk '{if($1>10) {print $1}}'
以个人目前的认知觉得,基本上sql语句能做到的事,linux命令也能够做到。
有这文档吗?
什么文档?
兄弟,怎么操作?请教。。。