来自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)
由
绪论
解释下,gawk是GNU+awk的简写,就是GNU他们开发出的,可以兼容awk。
使用awk你可以实现:
·
·
·
·
·
此外gawk还可以实现:
·
·
·
(这个可以进行网络通信让人期待)
1 开始
(1)C(面向过程的编程语言):我们都知道C语言是面向过程(procedural),我们在编写这类语言的时候需要指明每一步做什么。程序按照我们的设定运行。
(2)awk(数据驱动的语言):数据驱动(data-driven)是指我们我们找到所需的数据,然后指明对其做何操作。所以在数据驱动方面的编程采用awk是十分方便的。
(ylf注:这里的文件就是我刚开始强调的file,行或者别的单元结构就是record记录(一般以行的形式呈现),每个记录里面还有field(域))
一般awk程序的格式如下:
pattern{action}
pattern{action}
...
1.1 如何运行awk程序
$awk ‘awk-program’ input-file1 input-file2...
$awk -f awk-program-file input-file1 input-file2
这里用-f的参数指明用awk-program-file文件作为awk命令程序
注意:如果后面不跟文件名的话,则从shell标准输入上面读数据,这样我们每输入一行,它就处理一行。
给几个例子吧(粗体是我的输入,$这个不是输入,是shell的提示符号)
下面用到的data文件
id 0001 0002 0003 0004 0005 0006 |
例1:从data中找出年龄在25岁以上的人
$ awk '$3>25{print $0}' data id 0003 0005 0006 |
说明:默认情况下,以空格/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 ------------------- Total Salary: |
运行方式二:用可执行文件形式
首先
$ 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 -rwxrwxrwx 1 ylf ylf |
然后运行:
$ ./example01.awk data ------------------- Total Salary: |
我们发现运行起来就很方便了。注意这里多亏了
#!/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++)\ > > > 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{} \ Total size:698 |
如果不了解ls –l所罗列的列含义,看下面注释
第一列:权限用户,组,其他用户 第二列:该文件的链接数 第三列:该文件所属用户 第四列:该文件所属用户组(这里我用的模拟器,出现none了,大家忽略) 第五列:就是该文件大小,单位字节 第六列,第七列,第八列,表示该文件最后一次修改的月,日,时间。 第九列:文件名。 |
规范下大家写awk的代码,我之前也不是很规范
一般一个statement(包含模式 行为)作为一行,特殊情况多行使用\
所以上面例子可以采用如下写法
$ ls -l | awk 'x+=$5 > > -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 {} Total size:698B |
第二章待续。。