天天看點

shell學習筆記3---awk的執行過程(原創)

awk_script的組成

1、awk_script可以由一條或多條awk_cmd組成,兩條awk_cmd之間一般以newline分隔

2、awk_cmd由兩部分組成: awk_pattern { actions }

3、awk_script可以被分成多行書寫,必須確定整個awk_script被單引号括起來。

awk指令的一般形式

awk ' begin { actions }

awk_pattern1 { actions }

............

awk_patternn { actions }

end { actions }

' inputfile

其中 begin { actions } 和 end { actions } 是可選的。

awk的運作過程

1、如果begin 區塊存在,awk執行它指定的actions。

2、awk從輸入檔案中讀取一行,稱為一條輸入記錄。如果輸入檔案省略,将從标準輸入讀取

3、awk将讀入的記錄分割成字段,将第1個字段放入變量$1中,第2個字段放入$2,以此類推。$0表示整條記錄。字段分隔符使用shell環境變量fs或由參數指定。

4、把目前輸入記錄(資料行)依次與每一個awk_cmd中awk_pattern比較,看是否比對,如果相比對,就執行對應的actions。如果不比對,就跳過對應的actions,直到比較完所有的awk_cmd。

5、當一條輸入記錄比較了所有的awk_cmd後,awk讀取輸入的下一行,繼續重複步驟3和4,這個過程一直持續,直到awk讀取到檔案尾。

6、當awk讀完所有的輸入行後,如果存在end,就執行相應的actions。

其中iput_file可以是多于一個檔案的檔案清單,awk将按順序處理清單中的每個檔案。awk會先對輸入檔案執行完所有的action後再處理下一個檔案,看如下例子

$ cat file1

a 1

b 2

$ cat file2

d 4

c 3

$ awk '{print $0} {print $1}' file1 file2

a

b

d

c

另外有以下4點需要注意:

1、一條awk_cmd的awk_pattern可以省略,省略時不對輸入記錄進行比對比較就執行相應的actions。一條awk_cmd的actions也可以省略,省略時預設的動作為列印目前輸入記錄(print $0) 。一條awk_cmd中的awk_pattern和actions不能同時省略。

2、begin區塊和end區塊别位于awk_script的開頭和結尾。awk_script中隻有end區塊或者隻有begin區塊是被允許的。如果awk_script中隻有begin { actions } ,awk不會讀取input_file。

3、awk把輸入檔案的資料讀入記憶體,然後操作記憶體中的輸入資料副本,awk不會修改輸入檔案的内容。

4、awk的總是輸出到标準輸出,如果想讓awk輸出到檔案,可以使用重定向。

awk_pattern

awk_pattern模式部分決定actions動作部分何時觸發及觸發actions。awk_pattern可以是以下幾種類型:

正規表達式用作awk_pattern: /regexp/

1、awk中正規表達式比對操作中經常用到的字元:

^ $ . [] | () * // 通用的regexp元字元

+ : 比對其前的單個字元一次以上,是awk自有的元字元,不适用于grep或sed等

? : 比對其前的單個字元1次或0次,是awk自有的元字元,不适用于grep或sed等

2、舉例:

awk '/ *$0.[0-9][0-9].*/' input_file

布爾表達式用作awk_pattern,表達式成立時,觸發相應的actions執行。

1、表達式中可以使用變量(如字段變量$1,$2等)和/regexp/

2、布爾表達式中的操作符:

關系操作符: < > <= >= == !=

比對操作符: value ~ /regexp/ 如果value比對/regexp/,則傳回真;value !~ /regexp/ 如果value不比對/regexp/,則傳回真

舉例:

awk '$2 > 10 {print "ok"}' input_file

awk '$3 ~ /^d/ {print "ok"}' input_file

3、&&(與) 和 ||(或) 可以連接配接兩個/regexp/或者布爾表達式,構成混合表達式。!(非) 可以用于布爾表達式或者/regexp/之前。

舉例

awk '($1 < 10 ) && ($2 > 10) {print "ok"}' input_file

awk '/^d/ || /x$/ {print "ok"}' input_file

4、其它表達式用作awk_script,如指派表達式等

eg:

awk '(tot+=$6); end{print "total points :" tot }' input_file     // 分号不能省略

awk 'tot+=$6 {print $0} end{print "total points :" tot }' input_file // 與上面等效

actions

actions就是對awk讀取的記錄資料進行的操作。actions由一條或多條語句或者指令組成,語句、指令之間用分号(;)分隔。actions中還可以使用流程控制結構的語句。

awk的指令:

1、print 參數清單 : print可以列印字元串(加雙引号)、變量和表達式,是awk最基本的指令。參數清單要用逗号(,)分隔,如果參數間用空格分隔,列印出時參數值之間不會有空格。

2、printf ([格式控制符],參數) : 格式化列印指令(函數),文法與c語言的printf函數類似。

3、next : 強迫awk立刻停止處理目前的記錄,而開始讀取和處理下一條記錄,改變腳本控制過程。

4、nextfile : 強迫awk立刻停止處理目前的輸入檔案而處理輸入檔案清單中的下一個檔案

5、exit : 使awk停止執行而跳出。如果有end 存在,awk會去執行end 的actions。

6、getline:讀取下一行資料,但不改變腳本控制過程。

關于exit,next和getline函數可以參見筆者的另一篇部落格

http://czmmiao.iteye.com/blog/1885572

awk的語句: awk的語句主要是指派語句,用來給變量指派。

1、把直接值或一個變量值指派給變量。如果直接值是字元串要加雙引号。

awk 'begin {x=1 ; y=3 ; x=y ; print "x=" x " ; y=" y }'

2、把一個表達式的值指派給變量。表達式一般是數值表達式,也可以是其它表達式。

數值表達式: num1 operator num2

operator可以是: +(加) -(減) *(乘) /(除) %(取模) ^(求幂)

當num1或者num2是字元串而是不是數字時,無論是否加有雙引号,awk都視其值為0

條件選擇表達式: a?b:c (a為布爾表達式,b和c可以是表達式或者直接值)

當布爾表達式a的值為真時,整個表達式的值為b,a的值為假時,整個表達式的值為c

awk 'begin {x=3 ; x+=2 ; y=x+2 ; print "x=" x " ; y=" y }'

awk 'begin {x=3 ; y=x>4?"ok":4 ; print "x=" x " ; y=" y }'

3、為了友善書寫,awk也支援c語言文法的指派操作符: += -= *= /= %= ^= ++ --

流程控制結構

其中condition一般為布爾表達式,body和else-body是awk語句塊。

1、if (condition) {then-body} [else {else-body}]

2、while (condition) {body}

3、do {body} while (condition)

4、for (initialization; condition; increment) {body}

與c語言的for結構的文法相同。

5、break : 跳出包含它的for、while、do-while 循環

6、continue : 跳過for、while、do-while循環的body的剩餘部分,而立刻進行下一次循環的執行。

參考至:http://blog.chinaunix.net/uid-46353-id-2399597.html

                  http://blog.sina.com.cn/s/blog_6f02e1900100mmc5.html

本文原創,轉載請注明出處、作者

如有錯誤,歡迎指正

郵箱:[email protected]

作者:czmmiao  文章出處:http://czmmiao.iteye.com/blog/1885561

繼續閱讀