原题目:
处理以下文件内容,将域名取出并根据域名进行计数排序处理:(百度和sohu面试题)
答案的详细讲解请参考:
http://lidao.blog.51cto.com/3388056/1912219
文件内容:
1
2
3
4
5
|
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
|
要求结果:
1
2
3
|
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.org,mp3.etiantian.org, post.etiantian.org这几个域名。
www 出现了几次
mp3 出现了几次
post 出现了几次
第一个里程碑-简单容易理解的方法:
如果出现www则用a记录下www的重复数量,如果mp3出现则用b记录下mp3的重复数量,如果出现post则通过c记录下post的重复数量。
答案如下:
1
|
[root@oldboy32-vm1files]
#awk -F "[/]+"'$2~/www/{a++}$2~/mp3/{b++}$2~/post/{c++}END{print"www:"a,"mp3:"b,"post:"c}' url.txt
|
演示过程:
1
2
|
[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数组
还是刚才的思路,分三种情况,把不同的情况,这次是放入酒店的三个房间中。
1
2
|
[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会认为这是一个变量。
1
2
3
4
|
[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得到www或mp3或post的呢?
他们都是第二列!awk中可以用$2表示。
所以,这个数组就可以写为。
h[$2]++即可,自动对号入座,对号入座后进行自加的操作(自动加1)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
[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模式来解决。
1
2
|
[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自然有解决这个问题的方法,专用的循环。
1
2
3
4
|
[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