awk是一個強大的文本分析工具,相對于grep的查找,sed的編輯,awk在其對數據分析并生成報告時,顯得尤為強大。簡單來說awk就是把文件逐行的讀入,以空格為默認分隔符將每行切片,切開的部分再進行各種分析處理。
awk有3個不同版本: awk、nawk和gawk,未作特別說明,一般指gawk,gawk 是 AWK 的 GNU 版本。
awk其名稱得自于它的創始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首個字母。實際上 AWK 的確擁有自己的語言: AWK 程序設計語言 , 三位創建者已將它正式定義為“樣式掃描和處理語言”。它允許您創建簡短的程序,這些程序讀取輸入文件、為數據排序、處理數據、對輸入執行計算以及生成報表,還有無數其他的功能
代碼塊 | awk的所有代碼(目前這么認為)都是寫在語句塊中的。 語句塊可分為3類: BEGIN語句塊、END語句塊和main語句塊。 其中BEGIN語句塊和END語句塊都是的格式分別為BEGIN{...}和END{...},而main語句塊是一種統稱,它的pattern部分沒有固定格式,也可以省略,main代碼塊是在讀取文件的每一行的時候都執行的代碼塊。 BEGIN代碼塊: 在讀取文件之前執行,且執行一次 讀取文件時循環執行,(默認情況)每讀取一行,就執行一次main代碼塊 在讀取文件完成之后執行,且執行一次 | |||||||||
語法 | awk [options] 'pattern{action}'? ?file1 fiel1 awk的語法: 多個pattern{action}可以直接連接連用
| |||||||||
工作原理 | # awk-F: {print $1,$3}' /etc/passwd (1)awk使用一行作為輸入,并將這一行賦給內部變量$0,每一行也可稱為一一個記錄,以換行符結束 (2)然后,行被: (默認為空格或制表符)分解成字段(或域),每個字段存儲在已編號的變量中,從$1開始,最多達100個字段 (3)awk如何知道用空格來分隔字段的呢?因為有一個內部變量FS來確定字段分隔符。初始時,FS賦為空格 (4)awk打印字段時,將以設置的方法使用print西數打印,awk在打印的字段間加上空格,因為$1,$3之間有一個逗號。逗號比較特殊,它映射為另一個內部變量,稱為輸出字段分隔符OFS, OFS默認為空格 (5)awk輸出之后,將從文件中獲取另行,并將其存儲在$0中,覆蓋原來的內容,然后將新的字符串分隔成字段并進行處理。該過程將持續到所有行處理完畢 | |||||||||
變量 | RS | 可設置表示輸入記錄分隔符的預定義(Record Separator)來改變每次讀取的記錄模式。 RS通常設置在BEGIN代碼塊中,因為要先于讀取文件就確定好RS分隔符。 RS指定輸入記錄分隔符時,所讀取的記錄中是不包含分隔符字符的。例如RS="a",則$0中一定不可能出現字符a 特殊的RS值用來解決特殊讀取需求: RS="":按段落讀取 RS兩種可能情況: | ||||||||
RT | 在讀取每條記錄之后,將其賦值給$0,同時還會設置NR、FNR、RT。 在awk每次讀完一條記錄時,會設置一個稱為RT的預定義變量,表示Record Termination。 當RS為單個字符時,RT的值和RS的值是相同的。 當RS為多個字符(正則表達式)時,則RT設置為正則匹配到記錄分隔符之后,真正用于劃分記錄時的字符。 當無法匹配到記錄分隔符時,RT設置為控制空字符串(即默認的初始值)。 | |||||||||
NR | 在讀取每條記錄之后,將其賦值給$0,同時還會設置NR、FNR、RT。 所有文件的行號計數器 | |||||||||
FNR | 在讀取每條記錄之后,將其賦值給$0,同時還會設置NR、FNR、RT。 是各個文件的行號計數器 | |||||||||
字段分割 | awk讀取每一條記錄之后,會將其賦值給$0,同時還會對這條記錄按照預定義變量FS劃分字段,將劃分好的各個字段分別賦值給$1 $2 $3 $4...$N,同時將劃分的字段數量賦值給預定義變量NF $N引用字段: N=0:即$0,引用記錄本身 方式: 讀取record之后,將使用預定義變量FS、FIELDWIDTHS或FPAT中的一種來分割字段。分割完成之后,再進入main代碼段(所以,在main中設置FS對本次已經讀取的record是沒有影響的,但會影響下次讀取)。
有FS、FIELDWIDTHS、FPAT三種獲取字段的方式,可使用PROCINFO數組來確定本次使用何種方式獲得字段。 PROCINFO是一個數組,記錄了awk進程工作時的狀態信息。 如果: PROCINFO["FS"]=="FS",表示使用FS分割獲取字段 |
ARGV? 數組,保存命令行本身這個字符串,如awk '(print 50)'? a.txt,這個命令中,ARGV[0]保存awk ARGV[1]保存a.txt:
ARGC? awk命令的參數的個數? ? ? ? ?FILENAME? awk命令所處理的文件的名稱
ENVIRON:當前環境變量及其值的關聯數組
自定義變量test :? awk -v test="test" 'begin{print test}'? ?awk ? 'begin{ test="test";print test}'?
-----------格式化輸出printf
format格式的指示符都以開頭,后跟一個字符:
%c:顯示字符的ASCII碼? ? ?%d, %i點十進制整數? ? ? ? ?%e,%E:科學計數法顯示數值? ? ? ? ? ? %f:顯示浮點數
%g,%G:以科學計數法的格式或浮點數的格式顯示數值? ? ? ?%s:顯示字符串? ? %u:無符號整數? ? ? ? %%顯示%自身
修飾符
N:顯示寬度? ? ? ? ? ? ? ? ?-:? 左對齊? ? ? ? ? ? ?+:顯示數值符號
awk -F :'{printf "%-15s %i\n",$1,$3}'? ? ? ? /etc/passwd
--------------內置函數
length? ?返回string字符 キ中字符的個數
awk? ?-F : ‘{i1,while(i<NF){if(length)}}