Linux下的awk文本分析命令實例(一)

1.  入門實例
1.1 顯示最近登陸的5個賬號:  mysql

[root@localhost ~]# last -n 5 | awk '{print $1}'
root
root
root
root
reboot

1.2 若是隻是顯示/etc/passwd的帳戶:正則表達式

[root@localhost ~]# cat /etc/passwd |awk -F ':' '{print $1}'
root
bin
daemon
adm
lp
sync

1.3 若是隻是顯示/etc/passwd的帳戶和帳戶對應的shell,而帳戶與shell之間以tab鍵分割:sql

[root@localhost ~]# cat /etc/passwd |awk -F ':' '{print $1"\t"$7}' 
root    /bin/bash
bin    /sbin/nologin
daemon    /sbin/nologin
adm    /sbin/nologin
lp    /sbin/nologin
sync    /bin/sync
shutdown    /sbin/shutdown

1.4 若是隻是顯示/etc/passwd的帳戶和帳戶對應的shell,而帳戶與shell之間以逗號分割,並且在全部行添加列名name,shell,在最後一行添加"blue,/bin/nosh":shell

[root@localhost ~]# cat /etc/passwd |awk -F ':' 'BEGIN {print "name,shell"}  {print $1","$7} END {print "blue,/bin/nosh"} name,shell'
name,shell
root,/bin/bash
bin,/sbin/nologin
daemon,/sbin/nologin
adm,/sbin/nologin
lp,/sbin/nologin
sync,/bin/sync
shutdown,/sbin/shutdown
....
blue,/bin/nosh

1.5 搜索/etc/passwd有root關鍵字的全部行:apache

#awk -F: '/root/' /etc/passwd 
root:x:0:0:root:/root:/bin/bash

這種是pattern的使用示例,匹配了pattern(這裏是root)的行纔會執行action(沒有指定action,默認輸出每行的內容)。bash

搜索支持正則,例如找root開頭的: awk -F: '/^root/' /etc/passwdssh

1.6 搜索/etc/passwd有root關鍵字的全部行,並顯示對應的shelltcp

[root@localhost ~]# awk -F: '/root/{print $7}' /etc/passwd
/bin/bash
/sbin/nologin

1.7 其餘小示例:函數

$ awk '/^(no|so)/' test-----打印全部以模式no或so開頭的行。post

$ awk '/^[ns]/{print $1}' test-----若是記錄以n或s開頭,就打印這個記錄。

$ awk '$1 ~/[0-9][0-9]$/(print $1}' test-----若是第一個域以兩個數字結束就打印這個記錄。

$ awk '$1 == 100 || $2 < 50' test-----若是第一個或等於100或者第二個域小於50,則打印該行。

$ awk '$1 != 10' test-----若是第一個域不等於10就打印該行。

$ awk '/test/{print $1 + 10}' test-----若是記錄包含正則表達式test,則第一個域加10並打印出來。

$ awk '{print ($1 > 5 ? "ok "$1: "error"$1)}' test-----若是第一個域大於5則打印問號後面的表達式值,不然打印冒號後面的表達式值。

$ awk '/^root/,/^mysql/' test----打印以正則表達式root開頭的記錄到以正則表達式mysql開頭的記錄範圍內的全部記錄。若是找到一個新的正則表達式root開頭的記錄,則繼續打印直到下一個以正則表達式mysql開頭的記錄爲止,或到文件末尾。

2. awk內置變量示例
統計/etc/passwd:文件名,每行的行號,每行的列數,對應的完整行內容:
[root@localhost ~]# awk -F ':' '{print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0}' /etc/passwd
filename:/etc/passwd,linenumber:1,columns:7,linecontent:root:x:0:0:root:/root:/bin/bash
filename:/etc/passwd,linenumber:2,columns:7,linecontent:bin:x:1:1:bin:/bin:/sbin/nologin
filename:/etc/passwd,linenumber:3,columns:7,linecontent:daemon:x:2:2:daemon:/sbin:/sbin/nologin
filename:/etc/passwd,linenumber:4,columns:7,linecontent:adm:x:3:4:adm:/var/adm:/sbin/nologin
filename:/etc/passwd,linenumber:5,columns:7,linecontent:lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
filename:/etc/passwd,linenumber:6,columns:7,linecontent:sync:x:5:0:sync:/sbin:/bin/sync
filename:/etc/passwd,linenumber:7,columns:7,linecontent:shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
filename:/etc/passwd,linenumber:8,columns:7,linecontent:halt:x:7:0:halt:/sbin:/sbin/halt
filename:/etc/passwd,linenumber:9,columns:7,linecontent:mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
filename:/etc/passwd,linenumber:10,columns:7,linecontent:uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
filename:/etc/passwd,linenumber:11,columns:7,linecontent:operator:x:11:0:operator:/root:/sbin/nologin
filename:/etc/passwd,linenumber:12,columns:7,linecontent:games:x:12:100:games:/usr/games:/sbin/nologin
filename:/etc/passwd,linenumber:13,columns:7,linecontent:gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
filename:/etc/passwd,linenumber:14,columns:7,linecontent:ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
filename:/etc/passwd,linenumber:15,columns:7,linecontent:nobody:x:99:99:Nobody:/:/sbin/nologin
filename:/etc/passwd,linenumber:16,columns:7,linecontent:dbus:x:81:81:System message bus:/:/sbin/nologin
filename:/etc/passwd,linenumber:17,columns:7,linecontent:usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin
filename:/etc/passwd,linenumber:18,columns:7,linecontent:avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin
filename:/etc/passwd,linenumber:19,columns:7,linecontent:vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
filename:/etc/passwd,linenumber:20,columns:7,linecontent:rtkit:x:499:497:RealtimeKit:/proc:/sbin/nologin
filename:/etc/passwd,linenumber:21,columns:7,linecontent:abrt:x:173:173::/etc/abrt:/sbin/nologin
filename:/etc/passwd,linenumber:22,columns:7,linecontent:haldaemon:x:68:68:HAL daemon:/:/sbin/nologin
filename:/etc/passwd,linenumber:23,columns:7,linecontent:saslauth:x:498:76:"Saslauthd user":/var/empty/saslauth:/sbin/nologin
filename:/etc/passwd,linenumber:24,columns:7,linecontent:postfix:x:89:89::/var/spool/postfix:/sbin/nologin
filename:/etc/passwd,linenumber:25,columns:7,linecontent:ntp:x:38:38::/etc/ntp:/sbin/nologin
filename:/etc/passwd,linenumber:26,columns:7,linecontent:apache:x:48:48:Apache:/var/www:/sbin/nologin
filename:/etc/passwd,linenumber:27,columns:7,linecontent:avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
filename:/etc/passwd,linenumber:28,columns:7,linecontent:pulse:x:497:496:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
filename:/etc/passwd,linenumber:29,columns:7,linecontent:gdm:x:42:42::/var/lib/gdm:/sbin/nologin
filename:/etc/passwd,linenumber:30,columns:7,linecontent:sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
filename:/etc/passwd,linenumber:31,columns:7,linecontent:tcpdump:x:72:72::/:/sbin/nologin
filename:/etc/passwd,linenumber:32,columns:7,linecontent:zookeeper:x:500:500:Zookeeper:/home/zookeeper:/bin/bash

使用printf替代print,可讓代碼更加簡潔,易讀

awk -F ':' '{printf("filename:%10s,linenumber:%s,columns:%s,linecontent:%s\n",FILENAME,NR,NF,$0)}' /etc/passwd
awk -F ':' '{print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0}' /etc/passwd

   awk中同時提供了print和printf兩種打印輸出的函數。

   其中print函數的參數能夠是變量、數值或者字符串。字符串必須用雙引號引用,參數用逗號分隔。若是沒有逗號,參數就串聯在一塊兒而沒法區分。這裏,逗號的做用與輸出文件的分隔符的做用是同樣的,只是後者是空格而已。

   printf函數,其用法和c語言中printf基本類似,能夠格式化字符串,輸出複雜時,printf更加好用,代碼更易懂。

3. awk自定義變量

3.1. 下面統計/etc/passwd的帳戶人數:

[root@localhost ~]# awk '{count++;print $0;} END{print "user count is ", count}' /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......
zookeeper:x:500:500:Zookeeper:/home/zookeeper:/bin/bash
user count is  32

count是自定義變量。以前的action{}裏都是隻有一個print,其實print只是一個語句,而action{}能夠有多個語句,以;號隔開。

3.2. 這裏沒有初始化count,雖然默認是0,可是穩當的作法仍是初始化爲0:
[root@localhost ~]# awk 'BEGIN {count=0;print "[start]user count is ", count} {count=count+1;print $0;} END{print "[end]user count is ", count}' /etc/passwd 
[start]user count is  0
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
......
zookeeper:x:500:500:Zookeeper:/home/zookeeper:/bin/bash
[end]user count is  32
3.3. 統計某個文件夾下的文件佔用的字節數:
[root@localhost ~]# ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END{print "[end]size is ", size}'
[end]size is  86059

3.4 若是以M爲單位顯示:
[root@localhost ~]# ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END{print "[end]size is ", size/1024/1024,"M"}'
[end]size is  0.0820723 M

注意,統計不包括文件夾的子目錄。

4. 條件語句

統計某個文件夾下的文件佔用的字節數,過濾4096大小的文件(通常都是文件夾):

[root@localhost ~]# ls -l |awk 'BEGIN {size=0;print "[start]size is ", size} {if($5!=4096){size=size+$5;}} END{print "[end]size is ", size/1024/1024,"M"}' 
[start]size is  0
[end]size is  0.0508223 M
5.  循環語句

顯示/etc/passwd的帳戶:

[root@localhost ~]# awk -F ':' 'BEGIN {count=0;} {name[count] = $1;count++;}; END{for (i = 0; i < NR; i++) print i, name[i]}' /etc/passwd 
0 root
1 bin
2 daemon
3 adm
4 lp
5 sync
6 shutdown
7 halt
8 mail
9 uucp
10 operator
11 games
12 gopher
13 ftp
14 nobody
15 dbus
16 usbmuxd
17 avahi-autoipd
18 vcsa
19 rtkit
20 abrt
21 haldaemon
22 saslauth
23 postfix
24 ntp
25 apache
26 avahi
27 pulse
28 gdm
29 sshd
30 tcpdump
31 zookeeper
相關文章
相關標籤/搜索