linux命令之awk
awk 是一個強大的文本分析工具,把檔案逐行的讀入,以空格為預設分割符將每行切片,切開的部分再進行各種分析處理。
awk命令形式:
awk [-F | -f | -v] `BEGIN{} // {command1;command2;....;commandN} END{}` file
[-F | -f | -v] : 大參數,-F指定分隔字元,-f呼叫指令碼,-v定義變數
` ` : 引用代碼塊
BEGIN : 初始化代碼塊,在對每一行進行處理之前,初始化代碼,(在指令碼中主要是引用全域變數,設定FS分隔字元)
// : 匹配樣式,可以是字串或者Regex
{} : 命令代碼塊,包含一條或者多條命令
; : 多條命令使用分號分隔
END : 結尾代碼塊,在對每一行進行處理之後在執行的代碼塊,主要是進行最終計算或輸出結尾摘要資訊。
awk 支援的算術運算:
+ - * / ^ % ++ -- += -= *= /= %=
awk 內建變數:
$0 表示整個當前行
$n 每行第n個欄位,n不能為0
NF 欄位數量變數
NR 每行的記錄號,多檔案處理是記錄遞增
FNR 每行的記錄號,多檔案處理時不遞增,每個檔案都從1開始
FS BEGIN時定義分隔字元
RS 輸入的記錄分隔字元,預設為分行符號
OFS 輸出欄位分隔符號,預設是空格
ORS 輸出記錄的分隔字元,預設是分行符號
樣本檔案emp_names
$ cat emp_names 46013 DURHAM JEFF MOBILE AL46015 STEEN BILL MOBILE AL46017 FELDMAN EVAN MOBILE AL46018 SWIM STEVE UNKNOWN AL46019 BOGUE ROBERT PHOENIX AZ46021 JUNE MICAH PHOENIX AZ46022 KANE SHERYL UNKNOWN AR46024 WOOD WILLIAM MUNCIE IN46026 FERGUS SARAH MUNCIE IN46027 BUCK SARAH MUNCIE IN46029 TUTTLE BOB MUNCIE IN
$ awk '{print $0}' emp_names #列印檔案emp_names中的所有欄位46013 DURHAM JEFF MOBILE AL46015 STEEN BILL MOBILE AL46017 FELDMAN EVAN MOBILE AL46018 SWIM STEVE UNKNOWN AL46019 BOGUE ROBERT PHOENIX AZ46021 JUNE MICAH PHOENIX AZ46022 KANE SHERYL UNKNOWN AR46024 WOOD WILLIAM MUNCIE IN46026 FERGUS SARAH MUNCIE IN46027 BUCK SARAH MUNCIE IN46029 TUTTLE BOB MUNCIE IN$ awk '{print $1,$2,$3,$4,$5}' emp_names #列印檔案emp_names中多個欄位46013 DURHAM JEFF MOBILE AL46015 STEEN BILL MOBILE AL46017 FELDMAN EVAN MOBILE AL46018 SWIM STEVE UNKNOWN AL46019 BOGUE ROBERT PHOENIX AZ46021 JUNE MICAH PHOENIX AZ46022 KANE SHERYL UNKNOWN AR46024 WOOD WILLIAM MUNCIE IN46026 FERGUS SARAH MUNCIE IN46027 BUCK SARAH MUNCIE IN46029 TUTTLE BOB MUNCIE IN
$ awk '/AL|AZ/ {print $3,$2,$5}' emp_names #列印檔案emp_names中匹配AL 、 AZ樣式的多個欄位JEFF DURHAM ALBILL STEEN ALEVAN FELDMAN ALSTEVE SWIM ALROBERT BOGUE AZMICAH JUNE AZ$ awk '$5~/AR/' emp_names #在第5個欄位中匹配樣式,沒有指定列印欄位,則列印所有欄位46022 KANE SHERYL UNKNOWN AR$ awk '$5!~/AR/' emp_names #在第5個欄位中匹配樣式,列印出不匹配的所有行(沒有指定列印欄位,列印所有欄位)46013 DURHAM JEFF MOBILE AL46015 STEEN BILL MOBILE AL46017 FELDMAN EVAN MOBILE AL46018 SWIM STEVE UNKNOWN AL46019 BOGUE ROBERT PHOENIX AZ46021 JUNE MICAH PHOENIX AZ46024 WOOD WILLIAM MUNCIE IN46026 FERGUS SARAH MUNCIE IN46027 BUCK SARAH MUNCIE IN46029 TUTTLE BOB MUNCIE IN$ awk '$5~/AR/ {print $1 ; print $2 ; print $3}' emp_names #將一行中多個欄位分行列印46022KANESHERYL
$ awk '{print $0 | "sort > /tmp/filez"} ' emp_names #將檔案emp_names中欄位排序,重新導向到/tmp/filez檔案中$ cat /tmp/filez 46011 TUTTLE BOB MUNCIE IN46012 STEEN BILL MOBILE AL46013 DURHAM JEFF MOBILE AL46017 FELDMAN EVAN MOBILE AL46018 BOGUE ROBERT PHOENIX AZ46019 SWIM STEVE UNKNOWN AL46021 JUNE MICAH PHOENIX AZ46022 KANE SHERYL UNKNOWN AR46027 BUCK SARAH MUNCIE IN46030 FERGUS SARAH MUNCIE IN46045 WOOD WILLIAM MUNCIE IN
$ awk -F":" '{print $1}' /etc/passwd #/etc/passwd是系統內建檔案 每行是用:分隔字元,所以需要指定分隔字元 也可以使用 awk '{FS=":"} {print $1}' /etc/passwd 這樣結果是一樣的rootdaemonbinsyssyncgamesmanlpmailnews...
$ cat awk.list BEGIN{FS=":"}{print $1}$ awk -f awk.list /etc/passwd #使用-f調用awk指令碼rootdaemonbinsyssyncgamesmanlp
$ awk '{FS=":"} {OFS="-"}{print $1,$3}' /etc/passwd #指定輸出欄位分隔符號root:x:0:0:root:/root:/bin/bash-daemon-1bin-2sys-3sync-4games-5man-6lp-7$ awk -F":" '{print "USER_NAME: "$1, "\nNUMBER: "$3}' /etc/passwd #按照自己想要的格式與內容輸出USER_NAME: root NUMBER: 0USER_NAME: daemon NUMBER: 1USER_NAME: bin NUMBER: 2USER_NAME: sys NUMBER: 3USER_NAME: sync NUMBER: 4USER_NAME: games NUMBER: 5
樣本檔案內容$ cat inventory hammers57.99drills229.99punches73.59drifts24.09bits551.19saws12314.99nails800.19screws80.29brads100.24
$ awk 'BEGIN {print "ITEM\tQUANTITY\tPRICE\tTOTAL"} {x=x+($2*$3)} {print $1"\t"$2"\t\t"$3"\t"$2*$3} END {print "Total Value of Inventory: " x}' inventoryITEMQUANTITYPRICETOTAL #BEGIN關鍵字hammers57.9939.95drills229.9959.98punches73.5925.13drifts24.098.18bits551.1965.45saws12314.991843.77nails800.19152screws80.2923.2brads100.2424Total Value of Inventory: 2241.66 #END關鍵字 x最後的值
awk本身是一個程式設計語言,另外還支援if語句,迴圈語句;用法類似C語言的編程