awk教程

来自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

·            10awk的函数库(A Library of awk Functions

·            11awk程序实践练习(Practical awk Programs

·            12gawk高级特征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

前言(ForeWord

  Michael BrennanAuthor of mawk March, 2001)写的,讲述了他是怎么写出mawk的。。推荐读读哈

绪论

解释下,gawkGNU+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

(这个可以进行网络通信让人期待)

1 开始

        首先区分下awkC的区别:

1C(面向过程的编程语言):我们都知道C语言是面向过程(procedural,我们在编写这类语言的时候需要指明每一步做什么。程序按照我们的设定运行。

2awk(数据驱动的语言):数据驱动(data-driven)是指我们我们找到所需的数据,然后指明对其做何操作。所以在数据驱动方面的编程采用awk是十分方便的。

      awk的工作模式:在文件的每行每行(或者别的单元结构)中搜索我们指定的模式(目标),当匹配到目标时候,执行我们指定的操作,然后awk程序继续读取下一行(下一个单元结构),继续匹配和执行,直至结尾。

ylf注:这里的文件就是我刚开始强调的file,行或者别的单元结构就是record记录(一般以行的形式呈现),每个记录里面还有field(域))

一般awk程序的格式如下:

pattern{action}

pattern{action}

...

   就是由一个模式(匹配用的规则)和一个行为组成,当成功匹配,则执行后面大括号里的行为。(注意action用大括号哦)

1.1 如何运行awk程序

    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

 

1data中找出年龄在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

 


第二章待续。。

 

你可能感兴趣的:(awk教程)