參考文獻:https://www.cnblogs.com/jiqianqian/p/7944013.html
awk是一個強大的文本分析工具。相較於sed常常一整行處理,awk則傾向於將一行數據切片,分成數個“字段”處理;簡單來說awk就是把文件逐行的讀入,以空格為默認分隔符將每行切片,切開的部分再進行各種分析處理。
語法:
awk '條件類型1{動作1} 條件類型2{動作2} ...' filename
awk [options] 'pattern{action}' file
1.查看最近5條登錄用戶和ip地址
awk工作流程是這樣的:讀入有’\n’換行符分割的一條記錄,然后將記錄按指定的域分隔符划分域,填充域,0則表示所有域,01表示第一個域,n表示第n個域。默認域分隔符是"空白鍵"或"[tab]鍵",所以1表示登錄用戶,$3表示登錄用戶ip,以此類推。
$ last -n 5|awk '{print $1"\t"$3}' lzyer 192.168.56.1 reboot boot
wtmp Sat
$ last -n 5|awk '{print $1,$3}' lzyer 192.168.56.1 reboot boot
wtmp Sat
只處理第一行的數據
$ last -n 5|awk 'NR==1{print $1,$3}' lzyer 192.168.56.1
2.print和printf
awk中同時提供了print和printf兩種打印輸出的函數。
其中print函數的參數可以是變量、數值或者字符串。字符串必須用雙引號引用,參數用逗號分隔。如果沒有逗號,參數就串聯在一起而無法區分。這里,逗號的作用與輸出文件的分隔符的作用是一樣的,只是后者是空格而已。
printf函數,其用法和c語言中printf基本相似,可以格式化字符串,輸出復雜時,printf更加好用,代碼更易懂。
1. 使用printf輸出的文本不會換行,如果需要換行,可以在對應的“格式替換符”后加入“\n”進行轉義
2. 使用printf輸出時,“指定的格式”與“被格式化的文本”之間,要用“,”隔開
3. 使用printf輸出時,“格式”中的“格式替換符”必須與“被格式化的文本”一一對應(個數要相同)
eg:
1.#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 2.awk -F ':' '{printf("filename:%10s,linenumber:%s,columns:%s,linecontent:%s\n",FILENAME,NR,NF,$0)}' /etc/passwd
3.正則匹配
搜索/etc/passwd有root關鍵字的所有行
awk -F: '/root/' /etc/passwd root:x:0:0:root:/root:/bin/bash
這種是pattern的使用示例,匹配了pattern(這里是root)的行才會執行action(沒有指定action,默認輸出每行的內容)。
搜索支持正則,例如找root開頭的: awk -F: ‘/^root/’ /etc/passwd
搜索/etc/passwd有root關鍵字的所有行,並顯示對應的shell
awk -F: '/root/{print $7}' /etc/passwd /bin/bash
這里指定了action{print $7}
4.awk內置變量
awk有許多內置變量用來設置環境信息,這些變量可以被改變,下面給出了最常用的一些變量。
ARGC 命令行參數個數
ARGV 命令行參數排列
ENVIRON 支持隊列中系統環境變量的使用
FILENAME awk瀏覽的文件名
FNR 瀏覽文件的記錄數
FS 設置輸入域分隔符,等價於命令行 -F選項
NF 瀏覽記錄的域的個數
NR 已讀的記錄數
OFS 輸出域分隔符
ORS 輸出記錄分隔符
RS 控制記錄分隔符
5.常用參數
1. -F awk -F: 'NR==1{print}' /etc/passwd root:x:0:0:root:/root:/bin/bash 2. -v var1=100 echo |awk -v var=$var1 '{print var}' 100
awk -v FS=":" 'NR==1{print}' /etc/passwd root:x:0:0:root:/root:/bin/bash awk -v FS=":" -v OFS="#" 'NR==1{print $1,$2}' /etc/passwd root#x
6. 關系運算符
關系運算符 | 含義 | 用法實例 |
< | 小於 | x<y |
<= | 小於等於 | x<=y |
> | 大於 | x>y |
>= | 大於等於 | x>=y |
== | 等於 | x==y |
!= | 不等於 | x!=y |
~ | 匹配 | x~/正則表達式/ |
!~ | 不匹配 | x!~/正則表達式/ |
7.其他栗子
舉例來說,在 /etc/passwd 當中是以冒號 ":" 來作為字段的分隔, 該文件中第一字段為帳號,第三字段則是 UID。那假設我要查閱,第三欄小於 10 以下的數據,並且僅列出帳號與第三欄, 那么可以這樣做:
$ cat /etc/passwd|awk '{FS=":"} $3<10 {print $0}' root:x:0:0:root:/root:/bin/zsh 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
統計數據例子:
$ cat pay.txt Name 1st 2nd 3th VBird 23000 24000 25000 DMTsai 21000 20000 23000 Bird2 43000 42000 41000
$ cat pay.txt|awk 'NR==1{printf "%10s %10s %10s %10s %10s\n",$1,$2,$3,$4,"Total"} \ NR>=2{total=$2+$3+$4 > printf "%10s %10d %10d %10d %10.2f\n",$1,$2,$3,$4,total}' Name 1st 2nd 3th Total VBird 23000 24000 25000 72000.00 DMTsai 21000 20000 23000 64000.00 Bird2 43000 42000 41000 126000.00