awk功能与sed相似,都是用来进行文本处理的,awk语言可以人文件或字符串中基于指定规则浏览和抽取信息,在抽取信息的基础上,才能进行其他文本操作。

我们可以把awk形容为一把剪刀,可以截取某个文本内容的指定区域字符

awk编程模型

第一阶段:读取输入文件之前,由BEGIN标识

第二阶段:主输入循环,对每个输入文件进行处理

第三阶段:读取输入文件完毕,由END标识

awk调用方法:

格式:awk -F[区域分隔符] ‘{awk程序段}’ 输入文件

awk程序段可以是print或其它命令参数

如果不加上-F,则以空格为分隔符


[root@localhost ~]# cat abc
leon win aaa
leon leon leon leon
[root@localhost ~]# awk '{print $1}' abc
leon
leon

打印出第一区域的字段,这里不加-F则以空格做分隔符


[root@localhost ~]# cat abc
leon win aaa
leon leon leon leon
aa
[root@localhost ~]# awk '/^$/{print "h"}' abc
h
h

这段的/^$/ 指的是空白行,即从头到结尾都是空内容,即代表空行,当区域到的行是空白行后,就打字h的字符


最常用的区域打印,如abc文件中内容有多个域,可以理解为段落,以空格或tab隔开

原理:

111222 333 aaaa 555

111aaaa之间是以空格来隔开,aaaa555是以tab来隔开,这里每个隔开的地方可以称为字符的区域字段

111为第1区域,222为第2区域,555为第5区域


[root@localhost ~]# cat abc
leon win aaa
leon 33 44 leon
aa
[root@localhost ~]# awk '{print $3}' abc
aaa
44

因为abc第三行只有1个区域,所以打印出来效果会是个空行

打印多区域则:awk ‘{print $1,$4}’ abc 这样就能打印出第1和第4区域字段


awk还可以以变量方法来定义打印

[root@localhost ~]# cat abc
leon win aaa
leon 33 44 leon
aa
[root@localhost ~]# awk 'BEGIN{a=1;b=2} {print $(a+b)}' abc
aaa
44

定义了ab的变量,最后a+b3,即打印出第3区域


-F为指定分隔符,可以指定任何字符为分隔如,如-F: -F, -Fa -F/ 等等

-F”\t”是以tab键为分隔符,这里\t有特殊的意义


[root@localhost ~]# cat abc
leon:win:aaa
leon 33 44 leon
[root@localhost ~]# awk -F: '{print $2}' abc
win

:为分隔符,打印出第2区域,刚好第2区域是win


[root@localhost ~]# awk 'BEGIN{FS=":"} $1~/root/' /etc/passwd
root:x:0:0:root:/root:/bin/bash

使用FS改变分隔符”:” ,打印出第1区域为root的行,其中~为正则表达式符号

其实FS=”:”这种写法相当于-F


表达式:如匹配abc文件中有多少空行,则执行表达式x+=1x=x+1

[root@localhost ~]# cat abc
leon:win:aaa
leon 33 44 leon
aa
[root@localhost ~]# awk '/^$/{print x+=1}' abc
1
2

结果就会打印出12,相当是1,然后再1+12,因为匹配出有2个空行


awk比较常用的例子:

截取整段IP

[root@localhost ~]# ifconfig eth0 | grep "inet addr" | awk '{print $2}'|awk -F: '{print $2}'
192.168.1.1

查看根分区的已使用比率


[root@localhost ~]# df -Th
文件系统      类型    容量  已用 可用 已用% 挂载点
/dev/mapper/VolGroup00-LogVol00
              ext3     19G  2.5G   15G  15% /
/dev/sda1     ext3     99M   11M   83M  12% /boot
tmpfs        tmpfs    252M     0  252M   0% /dev/shm
[root@localhost ~]# df -Th | grep "/$" | awk '{print $5}'
15%

这里注意了,用grep过滤出/,后面要加上$,代表/后面是空字符,这样才过滤出单独根分区的那一行出来,然后再通过awk去截取区域的字段


查看系统中UID的用户数量,而且UID要大于80,要从小到大排序

[root@localhost ~]# cat /etc/passwd | awk -F: '{if($3>80)print $1,$3}' | sort -k2n
dbus 81
sabayon 86
distcache 94
nobody 99
leon 500
tom 501
nfsnobody 65534

sort命令用于排序,后面再详细解释

先设定条件用if,指定第3区域,即/etc/passwd文件中的UID区域的字符数字大于80,然后再打印出第1和第3区域内容,然后进行有序排列


由于awk的功能十分强大,笔者学习能力有限,只介绍到这里,详细可以参考有关的书籍