1.简介
      awk是linux下的一个命令,他对其他命令的输出,对文件的处理都十分强大。
相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强
大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开
的部分再进行各种分析处理。其实他更像一门编程语言,他可以自定义变量,有条
件语句,有循环,有数组,有正则,有函数等。他读取输出,或者文的方式是一行
,一行的读,根据你给出的条件进行查找,并在找出来的行中进行操作,感觉他的
设计思想,真的很简单,但是结合实际情况,具体操作起来就没有那么简单了。
       awk有三种形势,awk,gawk,nawk,平时所说的awk其实就是gawk。

2.awk的工作原理
     awk 'BEGIN{ commands } pattern{ commands } END{ commands }'
     第一步:执行BEGIN{ commands }语句块中的语句;
     第二步:从文件或标准输入(stdin)读取一行,然后执行pattern{ commands }
                 语句块,它逐行扫描文件,从第一行到最后一行重复这个过程,直到文
                 件全部被读取完毕。
     第三步:当读至输入流末尾时,执行END{ commands }语句块。BEGIN语句
                 块在awk开始从输入流中读取行之前被执行,这是一个可选的语句块,
                  比如变量初始化、打印输出表格的表头等语句通常可以写在BEGIN语
                  句块中。 END语句块在awk从输入流中读取完所有的行之后即被执行
                  ,比如打印所有行的分析结果这类信息汇总都是在END语句块中完成
                  ,它也是一个可选语句块。 pattern语句块中的通用命令是最重要的部
                  分,它也是可选的。如果没有提供pattern语句块,则默认执行{ print }
                  ,即打印每一个读取到的行,awk读取的每一行都会执行该语句块。
     
    
3.awk工作模式    模式可以是以下任意一个:     /正则表达式/:使用通配符的扩展集。    关系表达式:使用运算符进行操作,可以是字符串或数字的比较测试。    模式匹配表达式:用运算符~(匹配)和~!(不匹配)。    BEGIN语句块、pattern语句块、END语句块。
       

4.实例
假设last -n 5的输出如下
[root@www ~]# last -n 5 <==仅取出前五行
root     pts/1   192.168.1.100  Tue Feb 10 11:21   still logged inroot   pts/1   192.168.1.100  Tue Feb 10 00:46 - 02:28  (01:41)
root     pts/1   192.168.1.100  Mon Feb  9 11:41 - 18:30  (06:48)
dmtsai   pts/1   192.168.1.100  Mon Feb  9 11:41 - 11:41  (00:00)
root     tty1                   Fri Sep  5 14:09 - 14:10  (00:01)
如果只是显示最近登录的5个帐号
#last -n 5 | awk  '{print $1}'
root
root
root
dmtsai
rootawk

工作流程是这样的:读入有'\n'换行符分割的一条记录,然后将记录按指定的域分
隔符划分域,填充域,$0则表示所有域,$1表示第一个域,$n表示第n个域。
默认域分隔符是"空白键" 或 "[tab]键",所以$1表示登录用户,$3表示登录用户ip,
以此类推。

如果只是显示/etc/passwd的账户
#cat /etc/passwd |awk  -F ':'  '{print $1}'  root
daemon
bin
sys
这种是awk+action的示例,每行都会执行action{print $1}。
-F指定域分隔符为':'。

如果只是显示/etc/passwd的账户和账户对应的shell,而账户与shell之间以tab键分割
#cat /etc/passwd |awk  -F ':'  '{print $1"\t"$7}'root    /bin/bash
daemon  /bin/shbin     /bin/shsys     /bin/sh

如果只是显示/etc/passwd的账户和账户对应的shell,而账户与shell之间以逗号分
割,而且在所有行添加列名name,shell,在最后一行添加"blue,/bin/nosh"。
cat /etc/passwd |awk  -F ':'  'BEGIN {print "name,shell"}  {print $1","$7}
END {print "blue,/bin/nosh"}'name,shell
root,/bin/bash
daemon,/bin/shbin,/bin/shsys,/bin/sh....
blue,/bin/nosh

搜索/etc/passwd有root关键字的所有行
#awk -F: '/root/' /etc/passwdroot:x:0:0:root:/root:/bin/bash
这种是pattern的使用示例,匹配了pattern(这里是root)的行才会执行action(没有
指定action,默认输出每行的内容)。
搜索支持正则,例如找root开头的: awk -F: '/^root/' /etc/passwd

搜索/etc/passwd有root关键字的所有行,并显示对应的shell
# awk -F: '/root/{print $7}' /etc/passwd             /bin/bash
这里指定了action{print $7}       

 
5,运算符

运算符描述
= += -= *= /= %= ^= **=    赋值    
?:    C条件表达式    
||    逻 辑或    
&&    逻辑与    
~ ~!    匹 配正则表达式和不匹配正则表达式    
< <= > >= != ==    关 系运算符    
空格    连接    
+ -    加,减    
* / &    乘,除与求余    
+ - !    一元加,减和逻辑非    
^ ***    求幂    
++ --    增加或减少,作为前缀或后缀    
$    字 段引用    
in    数组成员    

例子:awk 'BEGIN{a="b";print a++,++a;}' 0 2

6,awk的正则
匹配符描述
\Y    匹配一个单词开头或者末尾的空字符串    
\B    匹配单词内的空字符串    
\<    匹配一个单词的开头的空字符串,锚定开始    
\>    匹配一个单词的末尾的空字符串,锚定末尾    
\W    匹配一个非字母数字组成的单词    
\w    匹配一个字母数字组成的单词    
\'    匹配字符串末尾的一个空字符串    
\‘    匹配字符串开头的一个空字符串    

7,字符串函数
函数名描述
sub    匹配记录中最大、最靠左边的子字符串的正则表达式,并用替换字符串替换这些字符串。如果没有指定目标字符串就默认使用整个记录。替换只发生在第一次匹配的 时候    
gsub    整个文档中进行匹配    
index    返回子字符串第一次被匹配的位置,偏移量从位置1开始    
substr    返回从位置1开始的子字符串,如果指定长度超过实际长度,就返回整个字符串    
split    可按给定的分隔符把字符串分割为一个数组。如果分隔符没提供,则按当前FS值进行分割    
length    返回记录的字符数    
match    返回在字符串中正则表达式位置的索引,如果找不到指定的正则表达式则返回0。match函数会设置内建变量RSTART为字符串中子字符串的开始位 置,RLENGTH为到子字符串末尾的字符个数。substr可利于这些变量来截取字符串    
toupper和tolower    可用于字符串大小间的转换,该功能只在gawk中有效    

8,数学函数
函数名返回值
atan2(x,y)    y,x 范围内的余切    
cos(x)    余弦函数    
exp(x)    求 幂    
int(x)    取整    
log(x)    自然对 数    
rand()    随机数    
sin(x)    正弦    
sqrt(x)    平 方根    
srand(x)    x是rand()函数的种子    
int(x)    取 整,过程没有舍入    
rand()    产生一个大于等于0而小于1的随机数     
               

本文转自willis_sun 51CTO博客,原文链接:http://blog.51cto.com/willis/1845918,如需转载请自行联系原作者