一、awk簡介
awk的意思是報告生成器,能根據輸入資訊,把資訊格式化後顯示,繼而出現new awk(nawk)在windows上實作,gawk,awk實作在linux上。awk是一種程式設計語言,在linux/unix下對文本和資料進行處理,是一款強大程式設計工具。在指令行中使用,更多作為腳本來使用。
awk處理檔案和資料的方式:逐行掃描檔案,從第一行到最後一行,尋找比對的特定模式的行,并在這些行上進行操作。如果沒有指定處理動作,則把比對行列印,如果沒有指定模式,則所有行都處理。gawk是awk的GNU版本。可通過指令ll `which awk`檢視
Linux文本處理三劍客:
grep, egrep, fgrep: 文本過濾器
sed: 文本編輯(行編輯器)
awk: 文本格式化,報表生成器
awk工作過程
根據定義的模式,一次從文本中讀取一行,awk會對行做相應的切片,将每一行按照分割符進行切割。例如this is a test 使用空白字元做分隔符将它們分開,切割為this,is,a,test四個片,可以使用變量,分别對應為$1,$2,$3,$4代表四個切割片
二、awk用法
1、基本格式
gawk [options] 'program' file file ...
program程式: PATTERN { ACTION STATEMENT }
由語句組成,語句分隔符是";"
ACTION: print, printf
選項options:
-F[]:指明輸入字段分隔符;預設以空白為分隔符
-F[, ]:逗号或空格為分隔符
-v var=val: 變量指派,無須聲明,可直接調用
-f /path/from/awk_script
EX:
(1)、列印/etc/passwd中的第三行和第六行不同用法
(2)、運作awk腳本
2、awk的輸出指令print
print item1, item2, ...
item:
(1)字元串:用引導引用
print "htello","world"
(2)變量:顯示變量的值
print name
要點:
(1)item間用逗号,輸出為空白字元
(2)item可以為字元串、變量、數值等
(3)item如果省略,等于print $0
(4)輸出空白字元,print ""
EX:列印/etc/passwd中的所有使用者
3、變量
3.1 内置變量
(1)FS: input field seperator,輸入字段分隔符,預設為空白字元;
(2)RS:input record separator,輸入行分隔符 預設為換行符;
(3)OFS: output field separator,輸出字段分隔符,預設為空白字元;
(4)ORS:output record separator,輸出行分隔符, 預設為換行符;
(5)NF: number of field in current record,目前行的字段數;
(6)NR:行數,所有檔案統一計數;
(7)FNR:行數,各檔案分别計數;
(8)FILENAME:目前被讀取的檔案名
(9)ARGC:指令行參數的個數;
(10)ARGV:數組,儲存了指令行參數自身
3.2 自定義變量
-v var=val:
變量名命名規則:
區分字元大小寫
數字,字元,下劃線,不能以數字開頭
不能使用内置關鍵字
定義變量的位置:
(1) 可以program中定義變量;
(2) 通過-v選項定義變量;
4、printf指令
格式: printf format, item1, item2, ...
(1)要點:
(1) format是必須的;
(2) 不自動換行,需給換行符;\n
(3) 為每個item指定格式符;否則item無法顯示
(2)格式符:都以%開頭,後跟一個字元
%c: 顯示字元的ASCII碼;
%d,%i: 顯示十進制整數;
%e, %E: 科學計數法顯示數值;
%f: 顯示為浮點數;
%g, %G: 以科學計數法格式或浮點數格式顯示數值;
%s: 字元串
%u: 無符号的整數
%%: 顯示%自身
(3)修飾符:
#[.#]: 第一個#指定顯示寬度,例如%30s;第二個#表示小數點後的精度;
-: 左對齊,預設為右對齊
+:顯示數值符号
5、操作符:
(1)算術操作符:
x+y, x-y, x*y, x/y, x^y, x%y
-x: 負值
+x: 轉換為數值
#awk 'BEGIN{print 4*5}'
(2)字元串操作:字元串連接配接
#awk ‘BEGIN{print "hello" "awk"}’
(3)指派操作符:
=, +=, -=, *=, /=, %=, ^=
++, --
(4)比較操作符:
>, >=, <. <=, ==, !=
(5)模式比對符:
~:能比對為真
!~:不能比對為真
(6)邏輯操作符:
&& 與運算
|| 或運算
(7)條件表達式:
selector?if-true-expression:if-false-expression
相當于bash的:
if SELECTOR;then
if-true-expression
else
if-false-expression
(8)函數調用:
function_name(argu1,argu2,...)
6、PATTERN
(1) /regular expression/: 正規表達式,僅處理能夠被/regular expression/所比對到的行;
(2) relational expression:關系表達式,有真假之分,一般來說,其結果為非0或非空字元串時為“真”,否則,為“假”;
(3) line ranges:行範圍,類似sed或vim的位址定界法;startline, endline
(4) BEGIN/END: 特殊模式
BEGIN:程式執行前執行一次
END:程式執行後執行一次
(5) empty: 空模式,比對任意行;
7、常用的action
(1) Expressions 表達式,如變量指派
(2) Control statements 控制語句,如if,while等
(3) Compound statements 複合語句,如{}
(4) input statements 輸入語句
(5) output statements 輸出語句
8、控制語句
if (condition條件) { statement語句 } [ else statement ]
while (condition) { statement }
do statement while (condition)
for (expr1初值; expr2循環; expr3修正) statement
for (var in array) statement
switch (expression) {case VALUE or /REGEXP/:statement;...;default;statement}
break 結束循環
continue 結束本輪循環
delete array[index]
delete array
exit [ expression ]
{ statements }
8.1 if-else
文法:if (condition條件) statement [ else statement ]
if (condition) { statements; } [ else { statements; }]
用法:對awk取得的整行或行中的字段做條件判斷;
8.2 while循環
文法:while (condition) statement
while (condition) { statements }
條件為真時進行循環,直到為假退出;
用法:通常用于在目前行的各字段間進行循環;
8.3 do-while循環 了解
文法:do statement while (condition)
do { do-while-body } while (condition)
意義:至少執行一次循環體;
8.4 for循環
文法:for (expr1; expr2; expr3) statement
for (expr1; expr2; expr3) { statements }
for (varaiable assignment; condition; iteration process) { for-body }
for循環在awk中有一個專用于周遊數組元素:
文法:for (var in array) { for-body }
8.5 switch 了解
文法:switch (expression) {case VALUE or /REGEXP/: statement; ...; default: statementN}
8.6 break and continue
break [n]: 退出目前循環,n表示幾層循環
continue:提前結束本輪循環,直接進入下輪循環
8.7 next
提前結束對本行的處理而進入下一行的處理
9、Array 數組
關聯數組:array[index-expression]
index-expression: 索引表達式
可以使用任意字元串;
如果某數組元素事先不存在,在引用時,awk會自動建立此元素并将其值初始化為空串;
是以,若要判斷數組是否存在某元素,要使用“index in array”進行;
要周遊數組中的每個元素,要使用: for (var in array) ,var會周遊array的每個索引,是以,要顯示數組元素的值,要使用array[var]
weekdays
weekdays[mon]="Monday"
weekdays[tue]="tuesday"
...
for(i in weekdays) 此時i會周遊weekdays數組的每個索引,即mon,tue,而非元素的值"Monday"或"Tuesday"等
要擷取元素的值:weekdays[i]
EX:統計每一行中各單詞分别出現的次數
可定義一個數組,用單詞本身當索引,而元素的值存儲單詞出現的次數
10、函數
(1)内置函數
1)數值處理:
rand(): 傳回0和1之間一個随機數;
2)字元串處理:
ength([s]): 傳回指定字元串的長度
3)sub(r, s [, t])查找r在t中,把每行第一次出現的r替換為s
sub(ab,AB,$0)
4)gsub(r, s [, t]):查找r在t中,把所有出現的r替換為s
5)split(s, a [, r]): 以r為分隔符,s為字元串切割,并把結果儲存到a中
注意:awk的數組下标從1開始編号
6)substr(s, i [, n]): 從s表示的字元串中取子串,從i開始,取n個字元;
7)時間類的函數:
systime(): 取時間戳;
8)位運算函數:
and(v1,va2):
(2)自定義函數
function f_name(p,q)
{
...
}