大家好,又见面了,我是你们的朋友全栈君。
闲话: Linux 从来没有系统的学过,AWK 这个高端的东西更没有系统全面的学过,知道真正项目中遇到的时候才会想着系统的学习一下,今天先写一下AWK的数组使用,网上有很多这样的文章,但是很多地方都没有讲的很细,所以看了半天还是一知半解,今天来细细的分析一下(本人忘心大,所以每次都的写的很细,以便以后能看懂,大牛或者觉得繁琐的请略过。
)
先简单说明一下awk吧
1. 官方解释AWK
awk :适用程序,一种unix工具 就是一个强大的文本分析工具,相对于grep查找、sed的编辑,awk在对数据分析并生成报告的时候,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种处理。
用法:
1) awk [ -F separator] ‘{pattern action}’ fileName
或者2)awk [ -F separator] ‘ pattern {action}’ fileName
2. 个人理解
像一个for循环,逐行读入文件内容(或者管道传输过来的值) ,然后使用分隔符将每行切片(用户可以指定自己想使用的分隔符)
3. AWK数组
因为awk中数组的下标可以是数字和字母,数组的下标通常被称为关键字(key)。和Java等数组不一样,Java等数组下表只能是数字。其实这里的数组相当于Java等语言中的Map。 AWK 的下标是关键字。值和关键字都存储在内部的一张针对key/value应用hash的表格里。由于hash不是顺序存储,因此在显示数组内容时会发现,它们并不是按照你预料的顺序显示出来的。数组和变量一样,都是在使用时自动创建的,awk也同样会自动判断其存储的是数字还是字符串。一般而言,awk中的数组用来从记录中收集信息,可以用于计算总和、统计单词以及跟踪模板被匹配的次数等等。 说了一大堆,如果你没看太懂,你只要记住把awk数组看成是Map就可以
eg: a[1] = 5 a[2] = 6 其实相当于 map.key = 1 map.value = 5 map.key=2 map.value=6 这也就说是为什么下表可以是数字或者字母。
4. 举例
1)[root@admin home]# cat awk.txt aaa
bbb
ccc
aaa
bbb
aaa
统计一下awk.txt文件中每个字符串名出现的次数:cat awk.txt | awk ‘{a[$1]++} END { for (i in a) {print i,a[i]}}’
a[1]++ : 就是awk 数组的形式, a 是数组名称, [1]做为key . 现在我们需要计算每个字符串出现的次数,所以需要把扫描到的相同的字符串名分别存储起来 ,就是键值对的数组,这里的键—对应的就是字符串,如aaa,值 — 对应的就是aaa出现的次数。数组a中的下标
awk数组不需要定义,可以直接赋值。
2) 有文件file.log内容如下:
http://www.sohu.com/aaa
http://www.sina.com/111
http://www.sohu.com/bbb
http://www.sina.com/222
http://www.sohu.com/ccc
http://www.163.com/zzz
http://www.sohu.com/ddd
要统每个域名出现次数:
http://www.sohu.com 4
http://www.sina.com 2
http://www.163.com 1
答案是: awk -F / ‘{a[$3]++} END{for(i in a){print i,a[i] | “sort -r -k 2”}}’ file.log;
-F参数是制定awk分隔符,这里制定的是 /,所以每行被分成4个部分。
sort 的-r是降序,-k是按照第几组字符排序,从1开始。
a可以理解成key-value形式的对象,域名做key 个数做value。
在end动作里完成对结果a的打印
3) awk统计ip访问次数(进阶) 现在有一个文件,数据量大概在200多万条记录,想用shell的awk做统计,文件的格式如下 #关键字#URL#IP地址# key1|url1|192.80.80.1
key1|url1|192.80.80.1
key1|url2|192.80.80.2 key1|url1|192.80.80.2 key2|url1|192.80.80.1 key2|url2|192.80.80.2 key2|url1|192.80.80.2 现在想要统计的结果是:查看同一个关键字和URL总的访问的次数,以及多少个不同的IP,输出到一个文件中
awk -F”|” ‘{a[1″ “2]++;b[1” “2” “3]++}(b[1” “2” “3]==1){++c[1” “2]}END{ for (i in a) print i,c[i],a[i]}’ file
看起来很复杂,其实分开理解还算简单
有三个值 a[1″ “2] 很好理解key url为关键字的访问次数。 就是理解为就是key url为关键字的 然后 a[1” “2]++ 可以理解为如果以1″ “2为关键字的。如果存在了就增加1,如果还不存在,就设值为1
那算多少个不同的IP怎么算呢? 单纯的想,做法应该是如果 #关键字#URL#IP地址# 是第一次出现, key url为关键字的访问IP肯定要+1 ,但是如果不是第一次出现,那此IP之前已经计算过了。就不用计算了。翻译为代码就是 (b[1″ “2” “3]==1){++c[1” “
再看一下:处理方法就是:
依次加载一行(for 循环/awk) 如果以1″ “2为关键字的。如果存在了就增加1,如果还不存在,就设值为1 a[1” “2]++
如果 #关键字#URL#IP地址# 是第一次出现, key url为关键字的访问IP肯定要+1 ,但是如果不是第一次出现,什么都不需要做 {b[1″ “2” “3]++}(b[1” “2” “3]==1){++c[1” “2]}
现在再看是不是就好理解了,最后结果为:
key2 url2 1 1 key1 url1 2 3 key2 url1 2 2 key1 url2 1 1
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/161639.html原文链接:https://javaforall.cn