awk從簡單到復雜
語法
awk [options] 'script' var=value file(s)
或
awk [options] -f scriptfile var=value file(s)
或
awk [options] 'pattern{action}' FILE ....
選項參數說明:
-F fs or --field-separator fs
指定輸入文件折分隔符,fs是一個字符串或者是一個正則表達式,如-F:。
-v var=value or --asign var=value
賦值一個用戶定義變量。
-f scripfile or --file scriptfile
從腳本文件中讀取awk命令。
-mf nnn and -mr nnn
對nnn值設置內在限制,-mf選項限制分配給nnn的最大塊數目;-mr選項限制記錄的最大數目。這兩個功能是Bell實驗室版awk的擴展功能,在標準awk中不適用。
-W compact or --compat, -W traditional or --traditional
在兼容模式下運行awk。所以gawk的行為和標準的awk完全一樣,所有的awk擴展都被忽略。
-W copyleft or --copyleft, -W copyright or --copyright
打印簡短的版權信息。
-W help or --help, -W usage or --usage
打印全部awk選項和每個選項的簡短說明。
-W lint or --lint
打印不能向傳統unix平臺移植的結構的警告。
-W lint-old or --lint-old
打印關於不能向傳統unix平臺移植的結構的警告。
-W posix
打開兼容模式。但有以下限制,不識別:/x、函數關鍵字、func、換碼序列以及當fs是一個空格時,將新行作為一個域分隔符;操作符**和**=不能代替^和^=;fflush無效。
-W re-interval or --re-inerval
允許間隔正則表達式的使用,參考(grep中的Posix字符類),如括號表達式[[:alpha:]]。
-W source program-text or --source program-text
使用program-text作為源代碼,可與-f命令混用。
-W version or --version
打印bug報告信息的版本。
其中pattern包括以下幾種:
地址定界
模式(包括正則表達式)
表達式
BEGIN(命令執行前預處理操作)
END(命令執行後的操作)
pattern通過,才會執行{action},當然pattern也可以省去,不匹配只執行動作。
action:
定義變量(數組)
語句(if、while、for)
輸出(print、printf)
awk內置的變量:
NF : 當前處理行一共多少字段
FS : 輸入字段分隔符,默認空格
OFS : 輸出字段分隔符,默認空格
NR : 目前awk所處理的是第幾行數據
2、基本用法
示例1:
打印用戶為apache和zabbix用戶的用戶名、UID、處理行的字段總數、輸出行處於文件的第幾行、輸出符合條件的行最後一列
方法1:
# awk -F: 'BEGIN{OFS="*"} /^apache|^zabbix/ {print $1,$3,NF,NR,$NF}' /etc/passwd
zabbix*498*7*30*/sbin/nologin
apache*48*7*36*/sbin/nologin
方法2:
# awk 'BEGIN{FS=":";OFS="*"} /^apache|^zabbix/ {print $1,$3,NF,NR,$NF}' /etc/passwd
zabbix*498*7*30*/sbin/nologin
apache*48*7*36*/sbin/nologin
解析:
分隔符:有兩種表示方法,如方法1所示使用-F跟分隔符的方式,方法2中和輸出分隔符OFS一塊放入BEGIN{}模塊,默認輸出分隔符是空格。
NF:
表示文件內容的列數,所以$NF就表示最後一列。
模式:
/^apache|^zabbix/ 就是模式的匹配,模式寫入//就可以,表示匹配以apache或者zabbix開頭的行。
BEGIN:
在awk實際工作之前執行一次
舉例:
# awk 'BEGIN{FS=":"} {print $1,$3}' /etc/passwd
root 0
bin 1
...
# awk '{FS=":"} {print $1,$3}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin 1
...
可以看到第二個輸出結果和第一個結果不一樣,因為BEGIN的工作流程是這樣的:1、沒有BEGIN出現,不用事前執行一些動作;2、awk開始獲取第一行數據,以FS值為分隔符,此時的FS是空的,$0變量保存整行數據,$1保存第一個字段數據,$2保存第二個字段數據.........一直到最後;3、awk開始執行動作,FS=":" ---> 顯示$1,$3 ---> 獲取第二行數據,以FS值冒號為分隔符............。
在FS賦值之間就已經把第一行數據獲取完畢了。 所以 在有BEGIN的情況下,awk在獲取數據之前會執行一次BEGIN的動作, 而且只有這一次。 那麽END也就不難理解了,就是在操作完所有行數據以後所執行的一次動作。
示例2:
print和printf
# awk 'BEGIN{FS=":"}NR==5,NR==8{print $1,$3,"\t\t","This is",NR,"line"}' /etc/passwd
lp 4 This is 5 line
sync 5 This is 6 line
shutdown 6 This is 7 line
halt 7 This is 8 line
解析:
NR是表示第幾行,上面就是第5行到第8行的定界
在print裏面除了變量以外,其它字符都要加上引號。\t表示一個制表符TAB。不同的字段輸出的時候會以輸出字符分隔符隔開
除了表示字段數據的$0,$1,$2等,其他變量包括自定義變量都不用$號
但是可以明顯感覺上面的排版有點亂,這裏可以使用printf對輸出內容進行格式化。
下面進行格式化輸出
# awk 'BEGIN{FS=":"}NR==5,NR==8{printf "%-10s %5s %10s %2s %5s\n",$1,$3," This is",NR,"line"}' /etc/passwd
lp 4 This is 5 line
sync 5 This is 6 line
shutdown 6 This is 7 line
halt 7 This is 8 line
解析:
格式化常用格式化字符
\n 換行
\t 水平TAB鍵
%s 顯示字符串。 數值也可以當作字符串顯示
%d,%i 十進制整數。
%c 顯示字符ASCLL碼。
%e,%E 科學計數法顯示數值。
%f 浮點數顯示。
%n.mf n表示包括小數點在內的長度,m表示小數點後的長度。
%% 顯示%自身。
%u 無符號整數
修飾符:
- 左對齊
+ 顯示數值符號
0 以0代替多余的空格。
這裏需要註意的是%-10s %5s %10s %2i%5s\n這一段就是格式化語句,%-10s:表示10個字符寬度,“-”表示左對齊,printf不會自動換行,所以後面加了個\n。
示例3:表達式
匹配UID大於等於500的相應信息
# awk 'BEGIN{FS=":"}$3>=500{printf "%-10s %5s %10s %2s %5s\n",$1,$3,"This is",NR,"line"}' /etc/passwd
nfsnobody 65534 This is 23 line
nexus 500 This is 31 line
box 501 This is 32 line
示例4:添加說明
對上面的輸出添加說明
# awk 'BEGIN{FS=":";printf "%-10s %5s %12s %17s\n","USER","UID","SHELL","DESCRIPTION"}/bin\/bash\>/{printf "%-10s %5s %15s %10s %2i%5s\n",$1,$3,$7,"This is",NR,"line"}' passwd
USER UID SHELL DESCRIPTION
root 0 /bin/bash This is 1 line
nexus 500 /bin/bash This is 31 line
...
示例5:算數和自定義變量
計算同學總成績
# cat test.txt
User English Math Music
zhangsan 85 90 83
lisi 80 95 60
zhouwu 66 77 98
zhengwang 80 93 67
# awk 'NR==1{printf "%-10s %7s %6s %6s %6s\n",$1,$2,$3,$4,"Total"}NR>=2{total=$2+$3+$4;printf "%-10s %7s %6s %6s %6s\n",$1,$2,$3,$4,total}' test.txt
User English Math Music Total
zhangsan 85 90 83 258
lisi 80 95 60 235
zhouwu 66 77 98 241
zhengwang 80 93 67 240
解析:
NR==1表示第一行在第五列定義了一個字符串“Total”,也就是定義了一個變量。
NR>=2之後的內容表示當行數大於等於2的時候,每一行的Total的值等於第二列第三列和第四列的值相加。
未完待續...
參考:
http://f.dataguru.cn/thread-509133-1-1.html
awk從簡單到復雜