您的位置:首页 > 其它

awk指令详解的笔记

2012-08-31 17:02 162 查看
awk指令,给我的感觉是可以在任何一截的管道设卡,通过正则,排序,取值,等等的操作取出所需要的值。

昨天处理了一个需求,如果取出排名前100request最慢的请求,log是这样的

2012-08-3100:00:39,571slow/area.htmid:531TIME:117

2012-08-3100:00:42,262slowreqcom.taobao.pegasus.travel.biz.bo.impl.MywayManagerImpl.getBeenToPageWithCommentTIME:76

2012-08-3100:00:42,297slow/area.htmid:356TIME:176

2012-08-3100:00:46,082slowreqcom.taobao.pegasus.travel.biz.bo.impl.MywayManagerImpl.getBeenToPageWithCommentTIME:55

2012-08-3100:00:51,257slow/note_view.htmid:8415TIME:131

2012-08-3100:00:54,128slowreqcom.taobao.pegasus.travel.biz.bo.impl.MywayManagerImpl.getBeenToPageWithCommentTIME:64

2012-08-3100:00:54,134slow/area.htmid:8038TIME:126

2012-08-3100:00:58,103slowreqcom.taobao.pegasus.travel.biz.bo.impl.MywayManagerImpl.getBeenToPageWithCommentTIME:59

2012-08-3100:00:58,108slow/area.htmid:3887TIME:101

2012-08-3100:00:59,425slow/note_view.htmid:9584TIME:111

2012-08-3100:01:00,060slow/note_view.htmid:11035TIME:134

2012-08-3100:01:01,781slowreqcom.taobao.pegasus.travel.biz.bo.impl.WeatherManagerImpl.getWeatherTIME:98

2012-08-3100:01:01,782slow/weather.htmTIME:101

2012-08-3100:01:06,073slow/note_view.htmid:10941TIME:102

时间在最后面,

于是写了这样的一个awk

cattravel_time.log|grep-v"slowreq"|sed's/TIME://g'|awk'($4~/\.htm/){print$NF""$4}'|sort-nr|head-100

慢慢来整理吧。

awk基本的结构是pattern{action}用一个大括号把要执行的东西包起来,它以line为导向,就是上一个的结果会成为下一个的流输入,比如下面的

echo'aaaabbbb'|awk'{print$1},它会把echo的字符串作为输入,然后以空格为split,打印出第一个数据。

$的意思是Thedollarsignmeansthatwearereferingtoafieldorcolumninthecurrentline

通过命令行的形式,awk可以轻松的处理文本,比如有这样的一个文本

gold11986USAAmericanEagle
gold11908Austria-HungaryFranzJosef100Korona
silver101981USAingot
gold11984Switzerlandingot
gold11979RSAKrugerrand
gold0.51981RSAKrugerrand
gold0.11986PRCPanda
silver11986USALibertydollar
gold0.251986USALiberty5-dollarpiece
silver0.51986USALiberty50-centpiece
silver11987USAConstitutiondollar
gold0.251987USAConstitution5-dollarpiece
gold11988CanadaMapleLeaf


名字为coins.txt,指令:

awk'/gold/'coins.txt

可以遍历上面的coins.txt文件,取出里面没一行中包含gold的行,然后输出,如果我们把这个指令和之前的{}组合起来,可以创造一个更强大的功能

awk'/gold/{print$5,$6,$7,$8}'coins.txt

将以gold开头的,coins的名字打印出来

这是一个最简单的awk指令的模式

awk<searchpattern>{<programactions>}

首先awk会遍历输入文件的每一行,从中找出满足searchpattern的行,然后通过actions输出需要展现的内容,print的作用就很明显了,用来打印,后面跟的$4,$5被称为fieldvariable。记录了每一行变量的顺序,其中变量$0代表了正行的信息,这里便有了等价三兄弟:

awk'/gold/'conis

awk'/gold/{print}'conis
awk'/gold/{print$0}'conis
[/code]
awk指令还能添加if的判断,如果我们想看看coins中哪些coins是在1980年之前铸造的

awk'{if($3<1980)print$3,"",$5,$6,$7,$8}'coins.txt

这个例子有一些新的概念:

1没有searchpattern如果木有,则awk会匹配所有的行

2在print里面添加自己的元素

3如果if语句匹配成功,就执行后面的print

awk还能有wc的作用,看这个例子

awk'END{printNR,"coins"}'coins.txt

为了解释这个例子,需要引入一个awk的语法:

awk'BEGIN{<initializations>}
<searchpattern1>{<programactions>}
<searchpattern2>{<programactions>}
...
END{<finalactions>}'

begin意指在awk开始文件流扫描之前的一些初始化的操作。之后的是一系列最简单的awk格式,awk扫描每一行,然后和每一个searchpattern比较,然后输出。在扫描完之后,END用来执行在结束之前的最后的输出。

所以,

awk'END{printNR,"coins"}'coins.txt

的意思是在最后的时候打印出NR+coions,其中NR是一个变量,表示记录的数量。(这个是awk自己定义的变量,还有一些其他的,比如NF)


NR-NumberofRecord-当前处理的行是第几行(因为awk是流处理工具,一行一行处理的,所以NR在不停的自增1)

FNR-FileNumberofRecord-当前处理的行是当前处理文件的第几行

NF-NumberofFileds-当前行有多少列数据(这个在每行都会根据设定的分割符重新计算,默认分割符是任务长个空白符)其中$NF指最后一列


现在给出一个更复杂的,比如现在的金币价值425美元,我们想知道总共的价格,

awk'/gold/{ounces+=$2}END{print"value=$"425*ounces}'coins.txt

这里的ounces就是我们自己定义的变量,不断的把第二列的重量加起来,最后在结束之前调用END的print打印出价值
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: