首页 > 代码库 > 初学awk数组会遇到的几个常见问题

初学awk数组会遇到的几个常见问题

  • 原题目:

处理以下文件内容,将域名取出并根据域名进行计数排序处理:(百度和sohu面试题)

答案的详细讲解请参考:

http://lidao.blog.51cto.com/3388056/1912219


文件内容:

http://www.etiantian.org/index.html
http://www.etiantian.org/1.html
http://post.etiantian.org/index.html
http://mp3.etiantian.org/index.html
http://www.etiantian.org/3.html

要求结果:

mp3.etiantian.org 1
post.etiantian.org 2
www.etiantian.org 3

答案:

1
awk -F "/+" ‘{hotel[$2]++}END{for(pol in hotel) print pol,hotel[pol]}‘ url.txt|sort -rnk2


  • 有的小伙伴初学awk数组会有下面几个疑问。


    • 为何要使用awk数组。

    • 为何要使用$2作为房间号码。

我们结合这道题来看一下。


首先明确我们的目标,我们要什么结果?

这里我们简化问题,把目标简化为统计www,mp3.post重复了几次,读者可以自行调整,并统计www.etiantian.orgmp3.etiantian.org, post.etiantian.org这几个域名。

  • www 出现了几次

  • mp3 出现了几次

  • post 出现了几次

 

  • 第一个里程碑-简单容易理解的方法:

如果出现www则用a记录下www的重复数量,如果mp3出现则用b记录下mp3的重复数量,如果出现post则通过c记录下post的重复数量。

答案如下:

[root@oldboy32-vm1files]#awk -F "[/]+"‘$2~/www/{a++}$2~/mp3/{b++}$2~/post/{c++}END{print"www:"a,"mp3:"b,"post:"c}‘ url.txt

演示过程:

 [root@showawkfile]#  awk -F "[/]+"‘$2~/www/{a++}$2~/mp3/{b++}$2~/post/{c++}END{print"www:"a,"mp3:"b,"post:"c}‘ url.txt
www:3 mp3:1 post:2

虽然这样很容易理解,因为这里只有三种域名www,post,mp3的,一般工作上会有很多个域名,你就会疯了。

所以我们想要一个方法,一个东西(一个名字)可以装下这三种情况,并且互相不影响。

这个东西就是我们说的数组(酒店),这三个情况就是我们说的数组里面的元素(酒店房间)。

 

  • 第二个里程碑-简单实用awk数组

还是刚才的思路,分三种情况,把不同的情况,这次是放入酒店的三个房间中。

[root@show awkfile]#awk -F "[/]+" ‘$2~/www/{h["www"]++}$2~/mp3/{h["mp3"]++}$2~/post/{h["post"]++}END{printh["www"],h["mp3"],h["post"]}‘ url.txt
3 1 2

 提示:awk数组如果自己指定房间名字(数组元素名字),切记一定要加上双引号。否则awk会认为这是一个变量。

[root@show awkfile]#awk ‘BEGIN{h[www]=1;h[bbs]=2;print h[www],h[bbs]}‘
2 2
[root@show awkfile]#awk ‘BEGIN{h["www"]=1;h["bbs"]=2;printh["www"],h["bbs"]}‘
1 2

上面的例子就是如果不加上双引号,awk会认为是变量。

  • 第三个里程碑-对号入座

还是很麻烦怎么解决呢?

有什么方法让遇到相同的内容就进入相同的房间吗?

如果遇到www自动进入www房间

如果遇到MP3自动进入MP3房间

如果遇到post自动进入post房间

可以的,思考一下我们如何通过awk得到wwwmp3post的呢?

他们都是第二列!awk中可以用$2表示。

所以,这个数组就可以写为。

h[$2]++即可,自动对号入座,对号入座后进行自加的操作(自动加1)。

[root@show awkfile]#awk -F "[/.]+" ‘{h[$2]++;print h["www"]}‘ url.txt
1
2
2
2
3
3
[root@show awkfile]#awk -F "[/.]+" ‘{h[$2]++;print"www:"h["www"],"mp3:"h["mp3"],"post:"h["post"]}‘url.txt
www:1 mp3: post:
www:2 mp3: post:
www:2 mp3: post:1
www:2 mp3:1 post:1
www:3 mp3:1 post:1
www:3 mp3:1 post:2
这样虽然可以看到我们想要的结果,但是也显示出了执行过程,我们只想要结果呀!
  • 第四个里程碑-输出结果

只要最后的结果可以通过END模式来解决。

[root@show awkfile]#awk -F "[/.]+" ‘{h[$2]++}END{print"www:"h["www"],"mp3:"h["mp3"],"post:"h["post"]}‘url.txt
www:3 mp3:1 post:2

这是一个房间一个房间的把内容显示出来,还是那句话当房间很多很多的时候,你又疯了。

awk自然有解决这个问题的方法,专用的循环。

[root@show awkfile]#awk -F "[/.]+" ‘{h[$2]++}END{for(pol in h)print pol,h[pol]}‘ url.txt
www 3
mp3 1
post 2

 

  • 到此我们又重新理解了一次awk数组。回顾下开始我们的问题。


    • 为何要使用awk数组。

他可以进行比较复杂的计算,当然也可以完成我们最常用的统计(去重)。


    • 为何要使用$2作为房间号码。

如果不用$2,作为房间号码,我们就需要手动来指定房间,这将是个噩梦。

$2正好可以表示www,mp3,post这几个内容。当然也涉及到了之前的知识,选择合适的刀,切出你想要的东西。


  • 重新看下,hotel[$2]++是如何执行的,请看下图。


技术分享

  • 相关博客内容:

awk数组进行统计计数(去重)

http://lidao.blog.51cto.com/3388056/1912219 

awk数组进行累加(计算总和)

http://lidao.blog.51cto.com/3388056/1914563


本文出自 “李导的博客” 博客,请务必保留此出处http://lidao.blog.51cto.com/3388056/1918859

初学awk数组会遇到的几个常见问题