您的位置:首页 > 其它

我们为什么需要awk?

2013-12-07 01:33 405 查看

我们为什么需要awk?

我并不打算一上来就向大家介绍什么是awk,那样的话会比较枯燥,也许大家还没看完就睡着了...!所以我们先来看这样一个需求:现在我们手里有一个很大的历史记录文件,是cvs格式的,一共一百多万行,它记录了历年债卷行情数据,先截取部分给大家围观下

SECode,Symbol,Exchange,TradeDate,AI,LCClose,COpen,CHigh,CLow,CClose,CAVGPrice,CChg,CPChg,LDClose,DOpen,DHigh,DLow,DClose,DAVGPrice,DChg,DPChg,Voturnover,Vaturnover,CYi
eld,WAVGYield,Duration,Duration_Mod,Convexity,Duration_Ben,Duration_Dis,CYield_YH,CYield_C,CYield_C_BE,CYield_S,Convexity_Ben,Convexity_Dis,WYield_YH,WYield_C,WYield_C
_BE,WYield_S,SBYield_YH,SBYield_C,SBYield_C_BE,SBYield_S,DSymbol
2040002832,115001,CNSESZ,20101008,1.380822,94.240000,94.260000,94.500000,93.680000,94.500000,93.899549,.260000,.2759,95.585753,95.640822,95.880822,95.060822,95.880822,
95.280371,.295069,.3087,2792100.00,2621769.32,,,2.087907,2.000895,5.994424,,,4.348662,4.348643,4.302367,4.347453,,,,,,,4.348662,4.348643,4.302367,4.347453,SZ115001.bon
d
2040002804,111015,CNSESZ,20101008,3.660274,100.990000,100.520000,100.680000,100.520000,100.680000,100.570286,-.310000,-.3070,104.529726,104.180274,104.340274,104.18027
4,104.340274,104.230560,-.189452,-.1812,70000.00,70399.20,,,1.046702,,,.867698,1.012813,3.346489,3.346455,3.318917,3.232915,.062591,2.036171,,,,,,,,,SZ111015.bond
2040002545,120102,CNSESH,20101008,4.767507,103.280000,103.100000,103.280000,103.080000,103.100000,103.107353,-.180000,-.1743,107.933315,107.867507,108.047507,107.84750
7,107.867507,107.874860,-.065808,-.0610,68000.00,70113.00,,,5.145570,4.918702,31.892982,,,4.612360,4.612358,4.560365,4.353782,,,,,,,,,,,SH120102.bond
2040002544,120101,CNSESH,20101008,1.227397,100.770000,100.680000,100.680000,100.400000,100.580000,100.497297,-.190000,-.1885,101.909726,101.907397,101.907397,101.62739
7,101.807397,101.724694,-.102329,-.1004,148000.00,148736.00,,,.693151,,,.289372,.672169,3.107084,3.121846,3.097854,3.107084,.219446,1.073186,,,,,,,,,SH120101.bond
2040002807,111018,CNSESZ,20101008,1.477973,100.210000,100.340000,100.340000,100.340000,100.340000,100.340000,.130000,.1297,101.581452,101.817973,101.817973,101.817973,
101.817973,101.817973,.236521,.2328,1000.00,1003.40,,,5.796356,5.531129,38.767525,,,4.795160,4.795161,4.739016,4.719491,,,,,,,,,,,SZ111018.bond
2040001152,020212,CNIBEX,20101008,.131068,101.080000,101.029800,101.029800,101.000000,101.000000,101.009933,-.080000,-.0791,101.129151,101.160868,101.160868,101.131068
,101.131068,101.141001,.001917,.0019,30000000.00,30302980.00,2.458569,2.453341,1.927278,,,.028012,1.881032,2.459338,2.459328,2.444390,2.447644,.085048,5.488721,,,,,,,,
,IB020212.bond


如你所见,它有很多很多的列,现在我们要提取部分列数据出来进行分析,如何实现?肯定有小伙伴举手回答说: “使用C,C++,C#,java等语言一行一行的读取文件,然后将每一行分割,然后取出对应的列,结果写到另一个文件”. 但是我会告诉你其实我还有十几个这种不同的历史文件要处理吗?要我写十几个这样的小工具还不如杀了我算了。还好有awk,使用awk完成上述需求,只需要在命令行中输入下面这条命令:

awk -F, 'NR > 2 {printf "%s, %s, %s, %s, %s, %s, %s\n", $2, $4, $7, $8, $9, $10, $22}' BondsMarket.csv


不用怀疑,就这么简单,只要一条命令就搞定了。

awk之管中窥豹

相信看上面的例子后,各位小伙伴对awk应该有了一个感性的认识了. awk是一个强大的文本处理工具,但是它其实不仅仅是一个工具,还是一门语言。这个强大的工具的发明者是Alfred Aho 、Peter Weinberger 和 Brian Kernighan。但是这三个个家伙比较懒,没有给它认认真真的起一个名字,就简单的取了三个人的姓氏的首字母组合起来--AWK,大师们果然懒惰!
需求完成了,也见识到了awk的威力,该到我们好好的认识了解下awk了,先从上述示例解析开始.

1. “-F,”是awk的命令行选项,该选项用来指定记录的分隔符,这里我们指定“,”作为分隔符,如果我们要指定“|”作为分隔符那就是这样子 -F|. 当然-F选项不是必须的,如果没有的话它就以空格作为默认分隔符了.

2. 单引号内的内容是awk程序,这个例子中只有一条awk语句,awk的语句由模式(pattern)和与之相关的动作(action)组成,动作在{}内,规则如下:

pattern {action}

在我们的这个小例子中,NR > 2 是模式,NR是awk内置的一个变量,表示当前记录的行数.

3. printf是awk的格式化输出函数,和c语言格式化输出一样一样的.

4. $2,$4... 这些也是awk的内置变量,表示第2列,第4列...,不难理解这条awk语句的意思就是从第三行开始输出每一行的第2列,第4列,第7列,...,第22列.
上面我们通过实例解析初步了解了下awk, 算是管中窥豹吧。

awk之走马观花

前面我们管中窥豹一样的大致了解了下awk,那么接下来我就带各位小伙伴走马观花的围观下awk.

awk概要

awk的运行方式如下:

awk [option] -f program-file [--] file ...

awk [option] [--] program-text [--] file ...

awk有很多的option, -F只是其中之一,也是最常用的,这里就不一一介绍了,以后用到了再详细说明。

awk支持将awk程序写到文件中,然后通过-f来指定awk程序文件,那么对于常用的或者复杂点的awk程序我们就写到文件中, 这样不用每次都命令行中输入了,省时省力。

file就是我们要处理的文件了,可以输入多个文件,awk会顺序处理。如果没有指定file的话,awk就从标准输入读取数据。也许 有人问了,从标准输入读取的意义何在?它的意义绝不是要我们手动从键盘敲数据进去,而是利用管道.

awk程序

awk程序是有一系列"模式-动作"以及可选的用户自定义函数.

pattern { action statements }

pattern { action statements }

...

function name( parameter list ){ statement }

...

awk的变量、记录和字段

awk的变量是动态的,无需预先定义,当第一次使用时被实例化。变量的类型可以是浮点数数值或者字符串,同时兼有二者,取决于它的使用方式。

awk有一些内置变量,例如本文例子中的$2,NR等等。

awk的一条记录就是文件中的一行数据。

awk通过-F指定的字符将记录分割成一个个的字段。

awk的模式

awk有如下多种模式:

BEGIN

END

/正则表达式/

表达式

区间模式

空模式

BEGIN和END是awk的特殊模式,它们并不匹配任何输入。BEGIN模式在读取任何输入之前就被执行,而END是所有文件都处理完了之后再执行.比如我们可以BEGIN中输出一行头信息,而在END中输出一些统计信息。

对于正则表达式,它与之对应的动作只有在当前记录匹配该正则表达式才被执行。

当表达式为非0的时候,它与之对应的动作才会被执行,例如本文例子中的NR>2,就是一个表达式。

区间模式是用","分割的两个模式组成,形如begpat,endpat. begpat控制区间的开始,endpat控制区间的结束。例如:

awk 'NR == 2, NR == 4 {print $0}' file1

输出file1的2~4行。

如果模式缺失,那么awk就处理每一行。

awk的动作

awk的动作是由{}括起来的一条或者多条awk语句组成. 每条awk语句做一件事. 多条语句之间使用换行或者";"分割。

awk支持以下几类语句:

表达式

调用函数或者给变量赋值或者进行数学运算.

控制语句

控制awk程序的流程。awk使用和C语言类似的控制结构,如,if, for, while以及do等.

复合语句

复合语句是由使用{}括起来的一条或者多条语句组成。复合语句常作为if或者for等控制语句的执行体。

输入语句

使用getline命令或者next,nextfile命令.

输出语句

print或者printf.

删除语句

删除数组.

总结

本文从一个具体需求引出一段awk代码示例,然后通过对示例的解析来初步认识awk, 然后走马观花似的围观了下awk各个方面。后面有时间的话会陆续把个人用到的一些awk功能进行总结以供诸位小伙伴们围观。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: