作者:mlsx
摘自:http://bbs.xplore.cn
AWK是一种模式扫描合处理语言,其名称来自最初的作者Alfred V. Aho,Perter J. Weinberger和Brian W.Kernighan的字母缩写,最早的AWK是在AT&T的Bell实验室发明的。
Linux下面使用的AWK是GNU AWK。
AWK可以用来:
1.管理小型个人数据库
2.产生报表
3.产生索引
。。。。
AWK也是一种解释性的语言,,我们主要使用它来编写一些小的工具,解决某些大问题中的小问题,对于系统管理员而言特别有用。
下面以文件test1.dat来举例说明AWK的一些简单应用:
代码::
cat test1.dat
one 123-321 234/22 a
two 344-637 726/28 c
three 273-287 287/97 d
four 872-872 282/20 c
上面是test1.dat的内容,中间用空白字符隔开(可以是空格,制表符等)
首先我们要弄清楚几个概念:
1.记录(record)
记录是AWK从数据文件上读取的数据的基本单位。对于test1.dat文件而言,一条记录就是一行。
第一条记录:“one 123-321 234/22 a”
2.域(field)
域是为记录上被分隔的子字符串。以记录“one 123-321 234/22 a”为例子
第一栏 第二栏 第三栏 第四栏
one 123-321 234/22 a
一帮以空白字符来分隔相邻的域。
如果AWK的程序很段,那么就可以再命令行上直接输入:
awk '程序' 文件1,文件2.。。。。
比如打印输入文件的第二列
代码::
awk '{print $2}' test1.dat
123-321
344-637
273-287
872-872
如果程序较长,那就写入到一个脚本文件中,执行awk的格式如下:
awk -f 程序文件名 文件1,文件2.。。。
这个和一般的shell脚本不一样,一般的shell脚本自己把它看成可知行文件来执行。
AWK程序的文件不止一个时,执行AWK的格式如下:
awk -f 程序文件1 -f 程序文件2 。。。 文件1,文件2.。。。。。
现在我们来看看AWK程序的主要结构,AWK程序中主要语法是表示式{动作},因此一般的AWK程序形式象下面这样:
表达式1 {动作1}
表达式2 {动作2}
。。。
表示式n {动作n}
AWK也可以接受一般的关系判断如
代码::
>,<,>=,<=,==,!=
另外它还接受~(符合)及!~(不符合)两个关系运算符,比如
代码::
"Xplore" ~/or/
这个上面这一行是一个表达式,因为Xplore中包含可符合/or/的子字符串,顾该表达式返回true。
而动作是有许多AWK指令构成。AWK的指令合C语言的指令类似。比如:
AWK的I/O指令:print,printf(),getline.....
AWK 流程控制指令:if (..){ ...} else {...} while(....) {....}.....
一个标准的AWK程序分成三个部分:BEGIN{},{},END{},其中BEGIN{}部分是再程序开始时执行,不管是否有输入,{}是输入多少行,就执行多少行;END{}是在程序结束时执行,也只执行一次。
比如下面的程序.
代码::
$cat count.awk
BEGIN{
print "now,begin statistic the lines of file ";
count=1;
}
{
print "this is the " count " line";
count++;
}
END{
print "this is the end of file";
}
$ awk -f count.awk test1.dat
now,begin statistic the lines of file
this is the 1 line
this is the 2 line
this is the 3 line
this is the 4 line
this is the end of file
再说一说有关AWK的内部变量:
1.域变量
AWK内部的域变量及其含义如下:
域变量 含义
$0 为一字符串,其内容为目前AWK所读入的记录
$1 代表$0上第一个域的数据
$2 代表$0上第二个域的数据
......................
AWK还提供了一些其他内部变量,常用的有:
NF(Number of Fields)为一整数,表示域的数目,比如test1.dat上域数目就是4个
NR(Number of Records)为一整数,其值表示AWK意读入的记录条数
FILENAME 正在处理的数据文件名
还有一些AWK的内部函数,这些函数的用法和名称和perl相识,因此这里不详细说明,在后面的例子中大家可以看到。
现举出一些常用的例子,通过这些实例,会对AWK语言有深一步的了解。
1.输出所有输入行之中,字段的最大个数。
代码::
$awk '{if (NF>max) max=NF} END{print max} ' test1.dat
4
2.将一个文件里所有的空白行删除
代码::
$ awk 'NF>0' test1.dat
one 123-321 234/22 a
two 344-637 726/28 c
three 273-287 287/97 d
four 872-872 282/20 c
3.输出一个文件的偶数行
代码::
$ awk 'NR %2 ==0' test1.dat
two 344-637 726/28 c
four 872-872 282/20 c
4.输入范围是1到100的七个随机数
代码::
$ awk 'BEGIN{for (i=1;i<7;i++) print int(101*rand())}'
24
29
85
15
59
19
5.输出本目录下所有文件的字节数
代码::
]$ ls -l |awk '{x+=$5}; END{print x}'
15827
6.将系统上的所有用户名,按照字母顺序输出
代码::
$ awk 'BEGIN{FS=":";} {print $1 |"sort" }' /etc/passwd
adm
apache
bin
daemon
dbus
desktop
ftp
games
gdm
gopher
guest
halt
lp
mailnull
mlsx
mysql
news
nfsnobody
nobody
nscd
ntp
operator
pcap
plone
root
rpc
rpcuser
rpm
shutdown
smmsp
squid
sshd
sync
uucp
vcsa
webalizer
wpm
xfs
7.统计一个文件的总行数并输出
代码::
$ awk 'END{print "total",NR,"lines"}' test1.dat
total 4 lines
8.给文件添加行数并输出
代码::
1: root:x:0:0:root:/root:/bin/bash
2: bin:x:1:1:bin:/bin:/sbin/nologin
3: daemon:x:2:2:daemon:/sbin:/sbin/nologin
4: adm:x:3:4:adm:/var/adm:/sbin/nologin
5: lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6: sync:x:5:0:sync:/sbin:/bin/sync
7: shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8: halt:x:7:0:halt:/sbin:/sbin/halt
9: mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10: news:x:9:13:news:/etc/news:
11: uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
12: operator:x:11:0:operator:/root:/sbin/nologin
13: games:x:12:100:games:/usr/games:/sbin/nologin
14: gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
15: ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
16: nobody:x:99:99:Nobody:/:/sbin/nologin
17: rpm:x:37:37::/var/lib/rpm:/bin/bash
18: vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
19: nscd:x:28:28:NSCD Daemon:/:/sbin/nologin
20: sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
21: rpc:x:32:32:Portmapper RPC user:/:/sbin/nologin
22: rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
23: nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
24: mailnull:x:47:47::/var/spool/mqueue:/sbin/nologin
25: smmsp:x:51:51::/var/spool/mqueue:/sbin/nologin
26: pcap:x:77:77::/var/arpwatch:/sbin/nologin
27: ntp:x:38:38::/etc/ntp:/sbin/nologin
28: gdm:x:42:42::/var/gdm:/sbin/nologin
29: desktop:x:80:80:desktop:/var/lib/menu/kde:/sbin/nologin
30: mlsx:x:500:48:weiguozhao:/home/mlsx:/bin/bash
31: apache:x:48:0:Apache:/var/www:/sbin/nologin
32: webalizer:x:67:67:Webalizer:/var/www/html/usage:/sbin/nologin
33: guest:x:501:501::/home/guest:/bin/bash
34: wpm:x:502:502::/home/wpm:/bin/bash
35: dbus:x:81:81:System message bus:/:/sbin/nologin
36: plone:x:101:102:Plone User:/var/lib/plone2/main:/bin/false
37: squid:x:23:23::/var/spool/squid:/sbin/nologin
38: xfs:x:43:43:X Font Server:/etc/X11/fs:/sbin/nologin
39: mysql:x:103:104:MySQL server:/var/lib/mysql:/bin/bash
9.输出文件中包含‘one’的行
代码::
$ awk '/one/{print $0}' test1.dat
one 123-321 234/22 a
10.给该系统上的正规用户的邮箱列表(假设域名是cie.xtu.edu.cn)
代码::
$ awk 'BEGIN{FS=":";} {if ($3>499) print $1 "@cie.xtu.edu.cn"}' /etc/passwd