awk:文本三劍客之一
#報告生成器,主要用來實現格式化文本輸出,它能夠實現在處理文本文件時對文檔中的某字段有條件顯示并以非常美觀的文本;
它是編程語言的解釋器;它也是一種完整的編程語言,它支持條件判斷、循環、變量、數組、函數等等各種各樣的編程語言所能實現的功能。
用法:awk [options] ‘program’ FILE …
program: PATTERN{ACTION STATEMENTS}
PATTERN:awk在數據中查找的內容
ACTION STATEMENTS:動作語句,對查找的內容執行的一系列命令,多為awk內置的命令print和printf;多個語句之間用分號分隔;
注意:program中的字符串要加雙引號。
選項:
-F:指明從文件中輸入數據時用到的字段分隔符;默認空白字符且不限制空白字符的個數,即同一行中一個空白字符、兩個空白字符、三個空白字符等都是分隔符;
-v var=value: 自定義變量;
awk的print子命令
用法:print item1, item2, …
要點:
輸出時默認以空白為分隔符;
輸出的各item可以字符串,也可以是數值,還可以是當前記錄的字段(例如$1、$2等等)、變量或awk的表達式;其中數值在輸出時會被隱式轉換成字符串以字符格式輸出,但該數值參與運算時依然是數值;變量要想替換值一般不能用引號引起來;
省略item相當于print $0(即打印整行);
備注:打印/etc/fstab文件中后5行的第2和4字段;
AWK的變量:有內建變量和自定義變量兩類;awk中引用變量不需要加$,只有引用字段變量時才用加$,例如$1、$2;
①內建變量
FS:input field seperator,輸入字段分隔符,默認為空白字符;
OFS:output field seperator,輸出字段分隔符,默認為空白字符;
RS:input record seperator,輸入行分隔符,默認為換行符;
ORS:output record seperator,輸出行分隔符,默認為換行符;
NF:number of field,每行字段數量
{print NF}:打印行的字段數量
{print $NF}:打印行的最后一個字段值
NR:number of record, 行數或行號
FNR:各文件分別計數;行數或行號
FILENAME:文件名;
ARGC:命令行參數的個數;
ARGV:保存了命令行參數的數組;
修改內建變量默認值:例如,#awk -v FS=”:”或#awk -F:(修改輸入分隔符為冒號)
可以看到效果。。。。。。
②自定義變量
有兩種方法:
1>-v var=value
變量名區分字符大小寫;
2>在program中直接定義
awk的printf子命令:格式化輸出
用法:printf FORMAT, item1, item2, …
要點:
FORMAT必須給出;
FORMAT中需要分別為后面的每個item指定一個格式符
不會自動換行需要顯式給出換行控制符\n
格式符:每一個格式符還可以有它的修飾符
%c: 顯示字符的ASCII碼;
%d, %i: 顯示十進制整數;
%e, %E: 科學計數法數值顯示;
%f:顯示為浮點數;
%g, %G:以科學計數法或浮點形式顯示數值;
%s:顯示字符串;
%u:無符號整數;
%%: 顯示%自身;
修飾符:用于格式符前面控制格式符顯示的機制
#[.#]:第一個數字控制顯示的寬度;第二個#表示小數點后的精度,例如%3.1f
-: 左對齊,默認右對齊;
+:顯示數值的符號;
注意:幾乎所有的編程語言都支持格式化輸出(包括bash);bash中也支持使用print和printf,不僅僅是echo;
awk中的操作符
①算術操作符:
x+y, x-y, x*y, x/y, x^y, x%y:加,減,乘,除,次方,取模
-x:正數轉換為負數;
+x: 字符串轉換為數值;
②字符串操作符:默認只有一個,即沒有符號的操作符(表示字符串連接);
③賦值操作符:=, +=, -=, *=, /=, %=, ^=(次方等),++, —
④比較操作符:>, >=, <, <=, !=, ==
⑤模式匹配符:
~:是否匹配
!~:是否不匹配
⑥邏輯操作符:&&,||,!
⑦函數調用:規范的函數調用方式,區別于bash中的函數調用;
function_name(argu1, argu2, …):“argu1, argu2, …”為向函數傳遞的參數;
⑧條件表達式:selector?if-true-expression:if-false-expression
selector是條件表達式,若selector為真則執行if-true-expression,否則執行if-false-expression;
PATTERN:實現地址定界的功能
①empty:空模式,即匹配每一行;
②/regular expression/:正則表達式,僅處理能夠被此處的正則表達式匹配到的行;“//”為模式符號,凡是正則表達式都要放在模式符號中;
③relational expression: 關系表達式,結果有“真”有“假”,結果為“真”才會被處理;結果為非0值或非空字符串為真,否則為假;
④line ranges:行范圍;
startline,endline:/pat1/,/pat2/
注意:不支持直接給出數字的格式
⑤BEGIN/END模式
BEGIN{}: 僅在開始處理文件中的文本之前執行一次,比如打印表頭;若不對文件做處理則運行在BEGIN模式中;
END{}:僅在文本處理完成之后命令結束之前執行一次,比如打印處理結果;
蠻有意思的0.0
常用的action,有如下幾類;
①Expressions:表達式,例如“a=6”;
②Control statements:控制語句,例如if, while等;
③Compound statements:組合語句,即把多個語句組合起來當一個代碼塊,通常用花括號括起來;
④Input statements:輸入語句;
⑤Output statements:輸出語句;
awk控制語句
if(condition) {statments}(只有一個語句花括號可以省略,下同):
if(condition) {statments} else {statements}
while(conditon) {statments}
do {statements} while(condition)
for(expr1;expr2;expr3) {statements}
break
continue
delete array[index]:刪除數組中的某個元素
delete array:刪除整個數組
exit
{statements}
控制語句
(1)if-else:很少用到多分支語句
語法:if(condition) statement [else statement]
使用場景:對awk取得的整行或某個字段做條件判斷;
(2)while循環
語法:while(condition) statement,條件“真”,進入循環;條件“假”,退出循環;若首次條件判斷為假,則循環體執行0次。
使用場景:對一行內的多個字段逐一進行類似處理時以及對數組中的各元素逐一進行類似處理時使用
(3)do-while循環
語法:do statement while(condition),與while的區別在于先執行一次循環體再判斷;
(4)for循環:比while循環更簡潔更易懂
語法:for(expr1;expr2;expr3) statement
詳解:for(variable assignment變量賦值;condition條件判斷;iteration process變量迭代) {for-body循環體}
特殊用法:能夠遍歷數組中的元素;
語法:for(var in array_name) {for-body}
示例:
(5)switch語句:多分支if語句,類似bash中case語句,但是關鍵字不同;常用于字符串等值比較或模式匹配判斷;
語法:switch(expression) {case VALUE1 or /REGEXP/: statement; case VALUE2 or /REGEXP2/: statement; …; default: statement}:expression和“VALUE1 or /REGEXP/”
(6)break和continue
break [n]:跳出n層循環,控制行內循環(即字段間循環);
continue:跳出當前循環直接進入下一輪循環,控制行內循環;
(7)next:控制awk的內生循環(即行間循環)提前結束對本行的處理而直接進入下一行;
備注:使用while、do-while、for編寫的循環控制awk的行內循環;
(8)array:較多使用關聯數組;
關聯數組:array[index-expression]
index-expression:
①可使用任意字符串,字符串要加雙引號;
②如果某數組元素事先不存在,在引用時awk會自動創建此元素并將其值初始化為“空串”,當把該“空串”當數值使用時其值為零;
數組元素賦值詳見“2016.01.05-bash編程之數組和字符串處理(1)”
數組元素引用使用print而非$;
判斷數組中是否存在某元素要使用“index in array”格式進行判斷;
遍歷數組中的每個元素要使用for循環,格式為“for(var in array) {for-body}”,var會遍歷array的每個索引;
函數
(1)內置函數
數值處理:
rand():返回0和1之間一個隨機數,此處的隨機指首次隨機;
字符串處理:
length([s]):返回指定字符串的長度;
sub(r,s,[,t]):以r表示的模式來查找t所表示的字符中的匹配的內容,并將其第一次出現替換為s所表示的內容;該功能sed和grep更易用;
gsub(r,s,[,t]):以r表示的模式來查找t所表示的字符中的匹配的內容,并將其所有出現均替換為s所表示的內容;該功能sed和grep更易用;
split(s,a[,r]):以r為分隔符切割字符s并將切割后的結果保存至a所表示的數組中;awk中的數組下標從1開始;
(2)自定義函數:極少用;
原創文章,作者:All well,如若轉載,請注明出處:http://www.www58058.com/73872