来自GNU:http://www.gnu.org/software/gawk/manual/gawk.html#Printing
维护版权!!
不是闲着蛋疼,而是受到http://coolshell.cn上的一篇博文的启发,想好好学习awk这个脚本(刚开始,不知到叫它脚本对不对。。),而且这周末就要考英语六级了,于是的于是,把上面这个网址内容翻译翻译,希望能给后来awk-er点帮助,尤其那些懒得看English的人。。。into topic..
awk是一个能够在文档里选择你所需的记录并进行操作的程序。(这里大家弄清文档file和记录record的关系,awk可以说就是在这二者之上做文章的)
· 概述
· 前言(ForeWord)
· 绪论(Preface)
· 1、开始(Getting started with awk)
· 2、运行(Running awk and gawk)
· 3、正则表达式(Regular Expressions)
· 4、读入文件(Reading Input Files)
· 5、打印输出(Printing Output)
· 6、表达式(Expressions)
· 7、模式、行为和变量(Patterns|,Actions and Variables)
· 8、数组(Array in awk)
· 9、函数(Functions)
· 10、awk的函数库(A Library of awk Functions)
· 11、awk程序实践练习(Practical awk Programs)
· 12、gawk高级特征(Advanced Features of gawk)
剩下的章节如果有时间继续弄,暂时翻译学习前面的哈
· 13 Internationalization with gawk
· 14 Debugging awk Programs
· 15 Arithmetic and Arbitrary Precision Arithmetic with gawk
· 16 Writing Extensions for gawk
· Appendix A The Evolution of the awk Language
· Appendix B Installing gawk
· Appendix C Implementation Notes
· Appendix D Basic Programming Concepts
· Glossary
· GNU General Public License
· GNU Free Documentation License
· Index
由 Michael Brennan(Author of mawk, March, 2001)写的,讲述了他是怎么写出mawk的。。推荐读读哈
解释下,gawk是GNU+awk的简写,就是GNU他们开发出的,可以兼容awk。
使用awk你可以实现:
· Manage small, personal databases
· Generate reports
· Validate data
· Produce indexes and perform other document preparation tasks
· Experiment with algorithms that you can adapt later to other computer languages
此外gawk还可以实现:
· Extract bits and pieces of data for processing
· Sort data
· Perform simple network communications
(这个可以进行网络通信让人期待)
首先区分下awk与C的区别:
(1)C(面向过程的编程语言):我们都知道C语言是面向过程(procedural),我们在编写这类语言的时候需要指明每一步做什么。程序按照我们的设定运行。
(2)awk(数据驱动的语言):数据驱动(data-driven)是指我们我们找到所需的数据,然后指明对其做何操作。所以在数据驱动方面的编程采用awk是十分方便的。
awk的工作模式:在文件的每行每行(或者别的单元结构)中搜索我们指定的模式(目标),当匹配到目标时候,执行我们指定的操作,然后awk程序继续读取下一行(下一个单元结构),继续匹配和执行,直至结尾。
(ylf注:这里的文件就是我刚开始强调的file,行或者别的单元结构就是record记录(一般以行的形式呈现),每个记录里面还有field(域))
一般awk程序的格式如下:
pattern{action}
pattern{action}
...
就是由一个模式(匹配用的规则)和一个行为组成,当成功匹配,则执行后面大括号里的行为。(注意action用大括号哦)
(1)如果awk是一个短小的程序段,我们可以直接在命令行上运行,格式如下:
$awk ‘awk-program’ input-file1 input-file2...
(2) 如果awk是一个较长的程序,我们一般写成文件的形式,让后调用改文件执行:
$awk -f awk-program-file input-file1 input-file2
这里用-f的参数指明用awk-program-file文件作为awk命令程序
注意:如果后面不跟文件名的话,则从shell标准输入上面读数据,这样我们每输入一行,它就处理一行。
还有,上面程序段用单引号包围,是为了防止被shell解释。
给几个例子吧(粗体是我的输入,$这个不是输入,是shell的提示符号)
下面用到的data文件
id name age sex salary country info 0001 ylf 24 male 0 CN 0002 jack 25 male 10000 EN 0003 SB 30 male 0 JP 0004 Lily 23 female 10000 EN 0005 Lilei 28 male 1000 CN 0006 Wang 26 male 30000 CN |
例1:从data中找出年龄在25岁以上的人
$ awk '$3>25{print $0}' data id name age sex salary country info 0003 SB 30 male 0 JP 0005 Lilei 28 male 1000 CN 0006 Wang 26 male 30000 CN |
说明:默认情况下,以空格/tab作为输入文件的记录上field的分隔符,$1 $2 .. 表示每个记录上的第几个field,这样方便我们指定,$0表示整个记录,所以上面awk程序段表示$3(年龄)大于25岁的人,满足则执行{}里面的动作,即打印整个记录。
例2:不带文件的,打印出hello world(用到的begin是指在执行匹配前先执行的,一般用于初始化,后面详细解释)
$ awk 'BEGIN{print "hello world\n"}' hello world
|
例3:想它一直读取我们的输入,然后检查pattern,符合处理结果,不符合继续,做一个猜点数的游戏(1-20)
$ awk '$1==13 {print "win"}$1!=13 {print "NO"}' 1 NO 2 NO 3 NO 14 NO 12 NO 13 win
NO
|
细心的人发现,这个程序无法退出,在shell下用ctrl+d ,上面出现空行和no是因为啥都没输入,只输入<Enter>
例4:文件形式运行awk程序。我们想要从data中找出中国人(CN)的工资总和,并且格式化输出每个人的ID name salary country这几个field(域)
$ cat example01.awk #!/usr/bin/awk -f #sum init to 0 BEGIN {sum=0} #NR means number of records就是当前处理到的是第几条记录,这里是为了输出field NR==1 {printf "%5s %8s %8s %2s\n",$1,$2,$4,$5} #printf is similar to C :format print $6=="CN" {sum+=$5;printf "%5s %8s %8s %2s\n",$1,$2,$4,$5} END {printf "-------------------\nTotal Salary:%8s",sum} |
这里example01.awk是一个awk程序段:
#后面跟的是注释,不会被解释,这里要注意的是第一行,#!告诉shell解释器在哪里(我的安装在/usr/bin/下,有的人可能在/bin/下,这个用which awk命令查询下就好了),如果把example01.awk改成可执行文件的时候,就很重要了,如果直接用awk来运行则该行可以删去,下面再解释。
运行方式一:用awk -f 告诉它代码文件 数据文件
$ awk -f example01.awk data id name sex salary 0001 ylf male 0 0005 Lilei male 1000 0006 Wang male 30000 ------------------- Total Salary: 31000 |
运行方式二:用可执行文件形式
首先
$ chmod 777 example01.awk $ ls -l total 16 drwxr-xr-x 2 ylf ylf 4096 2013-06-10 20:19 ./ drwxr-xr-x 3 ylf ylf 4096 2013-06-10 19:33 ../ -rw-r--r-- 1 ylf ylf 192 2013-06-10 19:36 data -rwxrwxrwx 1 ylf ylf 342 2013-06-10 20:19 example01.awk |
然后运行:
$ ./example01.awk data id name sex salary 0001 ylf male 0 0005 Lilei male 1000 0006 Wang male 30000 ------------------- Total Salary: 31000 |
我们发现运行起来就很方便了。注意这里多亏了
#!/usr/bin/awk -f
这行命令哦
注意,这里稍微给大家解释下shell下的单引号与双引号的区别:知道的人跳过哈,我也是半桶水的。。 单引号:能够完全保护引号内的内容,变量啥的都不会被shell 解释,原样输出 双引号:也是使得引号内的内容让shell看起来就是一个完整参数,但是里面变量会被解释 给个测试,大家就心里有数,记住:awk最好都用单引号吧 $ declare x=3 $ echo $x
$ echo "$x"
$ echo '$3' $3 |
在awk规则里,模式和行为两个是可以省略的,如果你需要的话。
(1)如果模式被省略,则默认情况每个记录都会执行action.
(2)如果{action}被省略,则默认情况是打印改行。但是如果你写成{}只是没有里面的action,则默认啥都不做,就是匹配成功的那个记录啥都不做,执行空语句的意思。
例5:打印出每行的长度,并且长度大于20的记录打印出来,否则只打印长度
$ cat data1 hello world. I am edited by ylf. ylf is a boy,who now is a student in the university. he is so fool. I hope I can learn awk program, and in this way, another purpose, learn Englesh.
$ awk '{print length($0)} \ > length($0)>20 {print $0}' data1 12 19 52 ylf is a boy,who now is a student in the university. 14 80 I hope I can learn awk program, and in this way, another purpose, learn Englesh.
0 |
注意:1、这里data1最后一行是空行,所以长度为0;
2、还有这里用了反斜杠\这个是告shell改行还没有结束,在awk里面也有这个功能。这个东东很好用,可以增加代码的可读性。
3、这里用到了length()这个内建函数,下面在使用个rand()随机数生成器给大家举个例子,想告诉你们,C++能实现的,awk几乎也能实现,而且awk的速度和代码量都比C来的少。
例6:
$ awk 'BEGIN {for(i=1;i<=5;i++)\ > print 100*rand()\ > }\ > ' 23.7788 29.1066 84.5814 15.2208 58.5537 |
例7:统计文件大小
$ ls -l 总用量 2 -rwxr-xr-x 1 ylf None 515 六月 11 13:06 bbs-list -rw-r--r-- 1 ylf None 183 六月 11 13:12 data1
$ ls -l | awk 'x+=$5{} \ END {printf "Total size:%s\n",x}' Total size:698
|
如果不了解ls –l所罗列的列含义,看下面注释
第一列:权限用户,组,其他用户 第二列:该文件的链接数 第三列:该文件所属用户 第四列:该文件所属用户组(这里我用的模拟器,出现none了,大家忽略) 第五列:就是该文件大小,单位字节 第六列,第七列,第八列,表示该文件最后一次修改的月,日,时间。 第九列:文件名。 |
规范下大家写awk的代码,我之前也不是很规范
一般一个statement(包含模式 行为)作为一行,特殊情况多行使用\
所以上面例子可以采用如下写法
$ ls -l | awk 'x+=$5 > END {printf "Total size:%sB\n",x} > ' -rwxr-xr-x 1 ylf None 515 六月 11 13:06 bbs-list -rw-r--r-- 1 ylf None 183 六月 11 13:12 data1 Total size:698B
$ ls -l | awk 'x+=$5 {} END {printf "Total size:%sB\n",x} ' Total size:698B
|
第二章待续。。