作者: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 [email protected] [email protected] [email protected] [email protected] |