簡介
awk是一個強大的文本分析工具,尤其是在應對格式化比較好的日誌文件時,簡單來說awk就是把文件逐行的讀入,以空格爲默認分隔符(也可以指定分隔符)將每行切片處理。
語法
awk [選項參數] 'script' var=value file(s)
或
awk [選項參數] -f scriptfile var=value file(s)
awk的工作流程
awk工作流程是這樣的:讀入有'\n'換行符分割的一條記錄,然後將記錄按指定的域分隔符劃分域,填充域,$0則表示所有域也就是整條記錄(這和正則匹配出來是類似的),$1表示第一個域,$n表示第n個域。默認域分隔符是空格,當然也可以指定分隔符。
選項參數說明:
-F fs or --field-separator fs
指定輸入文件折分隔符,fs是一個字符串或者是一個正則表達式,如-F:。
-f scripfile or --file scriptfile
從腳本文件中讀取awk命令
-v var=value or --asign var=value
賦值一個用戶定義變量。
解析:-F指定了每行的片分隔符是冒號,輸出第一個分片和倒數第二個分片中間用逗號分隔
//假設我們要輸出supervisor這個程序的進程號 ,這個命令配合xargs可以方便於結束某些進程
ps -ef|grep 'supervisor'|awk '{print $2}'
//輸出
1630
比如有如下文件ip.txt
1 134.102.173.43
2 134.102.173.43
3 134.102.171.42
4 134.102.170.9
要統計出現次數最多的IP可以利用以下shell腳本:
cat ip.txt | awk '{print $2}' | sort | uniq -c | sort -n -r | head -n 1
最後如果不加head這一組可以統計從多到少的列表
解析:
awk '{ print $5}':取數據的低5域(第5列)
sort:對IP部分進行排序。
uniq -c:打印每一重複行出現的次數。(並去掉重複行)
sort -n -r:按照重複行出現的次序倒序排列。
head -n 5:取排在前5位的IP
內置變量
ARGC 命令行參數個數
ARGV 命令行參數排列
ENVIRON 支持隊列中系統環境變量的使用
FILENAME awk瀏覽的文件名
FNR 瀏覽文件的記錄數
FS 設置輸入域分隔符,等價於命令行 -F選項
NF 瀏覽的當前行中分片的個數
NR 已讀的記錄數
OFS 輸出域分隔符
ORS 輸出記錄分隔符
RS 控制記錄分隔符
常用的就是NF,如果是{print $(NF-1)}就是打印倒數第二個分片
下面,爲了便於舉例,我們把/etc/passwd文件保存成demo.txt。
root:x:0:0:root:/root:/usr/bin/zsh
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
示例:
$ awk -F ':' '{print $1, $(NF-1)}' demo.txt
函數
awk還提供了一些內置函數,方便對原始數據的處理。
toupper():用於將字符轉爲大寫。
tolower():字符轉爲小寫。
length():返回字符串長度。
substr():返回子字符串。
sin():正弦。
cos():餘弦。
sqrt():平方根。
rand():隨機數。
示例:
$ awk -F ':' '{ print toupper($1) }' demo.txt
條件表達式
awk允許指定輸出條件,只輸出符合條件的行。
#只輸出包含usr的行。
$ awk -F ':' '/usr/ {print $1}' demo.txt
# 輸出奇數行
$ awk -F ':' 'NR % 2 == 1 {print $1}' demo.txt
root
bin
sync
# 輸出第三行以後的行
$ awk -F ':' 'NR >3 {print $1}' demo.txt
sys
sync
#下面的例子輸出第一個字段等於指定值的行
$ awk -F ':' '$1 == "root" {print $1}' demo.txt
root
$ awk -F ':' '$1 == "root" || $1 == "bin" {print $1}' demo.txt
root
bin
if 語句
awk提供了if結構,用於編寫複雜的條件,if結構還可以指定else部分
#輸出第一個字段的第一個字符大於m的行。
$ awk -F ':' '{if ($1 > "m") print $1}' demo.txt
root
sys
sync
#包含else的
$ awk -F ':' '{if ($1 > "m") print $1; else print "---"}' demo.txt
root
---
---
sys
sync