一、前言
awk是一款非常棒的數(shù)據(jù)處理工具。相比與sed常常作用于一整行的處理,awk則比較傾向于將一行分成數(shù)個(gè)“字段”來處理。因此awk適用于處理小型數(shù)據(jù)。
二、語法說明
awk '條件類型1{動作1} 條件類型2{動作2} ...' filename
awk后面接兩個(gè)單引號并加上大括號{}來設(shè)置想要對數(shù)據(jù)處理的動作。awk可以處理文件也可以讀取來自前一個(gè)命令的standardoutput(標(biāo)準(zhǔn)輸出流)。awk主要是處理每一行字段內(nèi)的數(shù)據(jù),而默認(rèn)字段的分隔符為空格鍵或者[tab]鍵。舉例說明:
- 使用
last -n 5命令獲取最后五次登陸者的信息,結(jié)果如下:
[root@iZxvryruh5alhlZ ~]# last -n 5
root pts/1 115.200.208.227 Thu May 17 07:57 still logged in
root pts/1 36.24.123.198 Mon May 14 06:55 - 14:55 (08:00)
root pts/2 36.24.123.198 Mon May 14 06:54 - 06:55 (00:01)
root pts/1 36.24.123.198 Mon May 14 06:49 - 06:53 (00:04)
root pts/0 36.24.123.198 Sun May 13 14:39 - 00:39 (10:00)
- 若只想取出賬號和登陸者IP,且賬號與IP之間用[tab]分隔,如下:
[root@iZxvryruh5alhlZ ~]# last -n 5 | awk '{print $1 "\t" $3}'
root 115.200.208.227
root 36.24.123.198
root 36.24.123.198
root 36.24.123.198
root 36.24.123.198
如上所示,每一行每個(gè)字段都是有變量名稱的,那就是$1,$2,$3等變量名稱。分別代表以空格或[tab]分隔的第一個(gè)字符串、第二個(gè)字符串、第三個(gè)字符串。上述$1就是root,$3就是IP。還有一個(gè)變量$0,$0代表的是一整行數(shù)據(jù)。
三、處理流程
- 整個(gè)awk的處理流程是:
- 讀取第一行,并將第一行的數(shù)據(jù)填入$0,$1,$2等變量中;
- 根據(jù)條件類型的限制,判斷是否處理后面的動作;
- 做完所有的條件類型判斷和動作;
- 若還有后續(xù)的“行”的數(shù)據(jù),則重復(fù)1~3的步驟,直到所有的數(shù)據(jù)都讀完為止。
- awk的內(nèi)置變量:
awk為什么會知道我的數(shù)據(jù)有幾行幾列呢?那就需要awk的內(nèi)置變量幫忙了,如下表所示:
| 變量名稱 | 代表意義 |
|---|---|
| NF | 每一行($0)所擁有的字段總數(shù) |
| NR | 目前awk處理的是第幾行數(shù)據(jù) |
| FS | 目前的分隔字符,默認(rèn)是空格 |
繼續(xù)上面的last -n 5,如果我想要:1、列出所有賬號,2、列出目前處理的行數(shù),3、改行有多少個(gè)字段。那么可以寫成這樣:
[root@iZxvryruh5alhlZ ~]# last -n 5 | awk '{print $1 "\t lines:" NR "\t columes:" NF}'
root lines:1 columes:10
root lines:2 columes:10
root lines:3 columes:10
root lines:4 columes:10
root lines:5 columes:10
四、邏輯運(yùn)算符
之前說過,awk有條件判斷,那么自然會有一些邏輯運(yùn)算符了。如下表所示:
| 運(yùn)算符 | 代表意義 |
|---|---|
| < | 小于 |
| > | 大于 |
| <= | 小于等于 |
| >= | 大于等于 |
| == | 等于 |
| != | 不等于 |
我們來實(shí)際運(yùn)用一下邏輯判斷吧!在/etc/passwd當(dāng)中以“:”分隔來作為字段的分隔,該文件第一個(gè)字段為賬號,第三個(gè)字段為UID。我們需要查詢的是UID小于10的數(shù)據(jù),并只列出賬號和UID字段:
- 先來看看/etc/passwd的所有內(nèi)容:
[root@iZxvryruh5alhlZ ~]# cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:997:User for polkitd:/:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
nscd:x:28:28:NSCD Daemon:/:/sbin/nologin
mysql:x:1000:1000::/home/mysql:/bin/bash
- 列出UID小于10的數(shù)據(jù),并且只列出賬號和UID字段:
[root@iZxvryruh5alhlZ ~]# cat /etc/passwd | awk '{FS=":"} $3 < 10 {print $1 "\t" $3}'
root:x:0:0:root:/root:/bin/bash
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8
細(xì)心的人會發(fā)現(xiàn)第一行數(shù)據(jù)沒有發(fā)生變化,這是為什么呢?這是因?yàn)?,讀第一行的時(shí)候默認(rèn)還是以空格分隔的,雖然我們定義了FS=":",但也只能從第二行生效,怎么辦呢?我們需要預(yù)先設(shè)置變量,利用BEGIN這個(gè)關(guān)鍵字,這樣做:
[root@iZxvryruh5alhlZ ~]# cat /etc/passwd | awk 'BEGIN {FS=":"} $3 < 10 {print $1 "\t" $3}'
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8
五、總結(jié)
awk可以幫我們完成行數(shù)據(jù)的處理,條件判斷,基本運(yùn)算等。這里帶大家簡單介紹了一下,大家如果感興趣可以了解一下awk更高級的用法。