天天看點

awk的模式和動作

awk的模式和動作

【文法結構】

awk -F 'Pattern1{Action1};Pattern2{Action2}' input-file或

awk -F '{Action}' input-file

① -F 為字段分隔符。若不指定,預設會使用空格作為分隔符。 

② /Pattern/和{Action}需要用單引号引起來,防止shell作解釋。 

③ /Pattern/是可選的。如果不指定,awk 将處理輸入檔案中的所有記錄。如果指定一個模式,awk 則隻處理比對指定的模式的記錄。 

④ {Action} 為 awk 指令,可以是單個指令,也可以多個指令。整個 Action(包括裡面的所有指令)都必須放在{ 和 }之間。 

⑤ Input-file 要處理的目标檔案

⑥ Action必須被{}包裹,沒有被{}包裹的就是Pattern

【Pattern】

awk 可接受許多不同型态的 Pattern. 一般常使用 "關系表達式"(Relational expression) 來當成 Pattern。awk 通過判斷 Pattern 的值來決定是否執行其後所對應的Actions。以下是幾種常見的Pattern:

BEGIN

BEGIN 為 awk 的保留字, 是一種特殊的 Pattern.

BEGIN 成立(值為true)的時候是: "awk 程式一開始執行, 尚未讀取任何資料之前." 是以在 BEGIN { Actions } 文法中, 其 Actions 部份僅于程式一開始執行時被執行一次. 當 awk 從資料檔案讀入資料行後, BEGIN 便不再成立, 故不論有多少資料行, 該 Actions 部份僅被執行一次.一般常把 "與資料檔案内容無關" 與 "隻需執行ㄧ次" 的部分置于該Actions(以 BEGIN 為 Pattern)中.

例如:

BEGIN {

FS = "[ \t:]" # 于程式一開始時, 改變awk切割字段的方式

RS = "" # 于程式一開始時, 改變awk分隔資料行的方式

count = 100 # 設定變量 count 的起始值

print " This is a title line " # 印出一行 title

}

....... # 其它 Pattern { Actions } .....

有些awk程式甚至"不需要讀入任何資料行". 遇到這情況可把整個程式置于以 BEGIN 為 Pattern的 Actions 中.

例如 :

BEGIN { print " Hello ! the Word ! " }

注意 :執行該類僅含 BEGIN { Actions } 的程式時, awk 并不會開啟任何資料檔案進行處理.

END

END 為 awk 的保留字, 是另一種特殊的 Pattern.

END 成立(其值為true)的時機與 BEGIN 恰好相反, 為:"awk 處理完所有資料, 即将離開程式時"平常讀入資料行時, END并不成立, 故其對應的 Actions 并不被執行; 唯有當awk讀完所有資料時, 該 Actions 才會被執行

注意 : 不管資料行有多少, 該 Actions 僅被執行一次.

關系表達式

使用像 " A 關系運算符 B" 的表達式當成 Pattern.

當 A 與 B 存在所指定的關系(Relation)時, 該 Pattern 就算成立(true).

length($0) <= 80 { print $0 }

上式中 length($0)<= 80 是一個 Pattern, 當 $0(資料行)之長度小于等于80時該 Pattern 之值為true, 将執行其後的 Action (列印該資料行).

awk 中提供下列 關系運算符(Relation Operator)

運算符 含意

> 大于

< 小于

>= 大于或等于

<= 小于或等于

== 等于

!= 不等于

~ match

!~ not match

上列關系運算符除~(match)與!~(not match)外與 C 語言中之含意一緻.

~(match) 與!~(match) 在 awk 之含意簡述如下 :

若 A 為一字元串, B 為一正規表達式.

A ~B 判斷 字元串A 中是否 包含 能比對(match)B式樣的子字元串.

A !~B 判斷 字元串A 中是否 未包含 能比對(match)B式樣的子字元串.

$0 ~ /program[0-9]+\.c/ { print $0 }

$0 ~ /program[0-9]+\.c/ 整個是一個 Pattern, 用來判斷$0(資料行)中是否含有可 match /program[0-9]+\.c/ 的子字元串, 若$0 中含有該類字元串, 則執行 print (列印該行資料).

Pattern 中被用來比對的字元串為$0 時(如本例), 可僅以正規表達式部分表示整個Pattern.故本例的 Pattern 部分$0 ~/program[0-9]+\.c/ 可僅用/program[0-9]+\.c/表之

常量

常量有兩種類型,字元串常量和數值常量.字元串常量必須用引号括起來,數值常量不需要,如數值0和字元串"0"是不一樣的.

數值常量中,0代表假,非0的數值常量代表真

字元串常量中,空字元串為假,非空字元串為真

例如

1{print}

上式利用數值常量1作為一個邏輯值.

該式中數值常量為1非0為真

空Pattern

如果awk的語句中省略了pattern,即pattern為空,則代表永遠為真,并執行後面緊跟的action.如果action省略則預設action為print

{name=1}5

上式還原完整的格式為 空pattern {name=1}5 {print}.

正規表達式

直接使用正規表達式當成 Pattern; 此為 $0 ~ 正規表達式 的簡寫.

該 Pattern 用以判斷 $0(資料行) 中是否含有比對該正規表達式的子字元串; 若含有則成立(true) 執行其對應的 Actions.

/^[0-9]*$/ { print "This line is a integer !" }

與 $0 ~/^[0-9]*$/ { print "This line is a integer !" } 相同

混合 Pattern

之前所介紹的各種 Patterns, 其計算後結果為一邏輯值(True or False).awk 中邏輯值彼此間可通過&&(and), ||(or),  !(not) 結合成一個新的邏輯值.故不同 Patterns 彼此可通過上述結合符号來結合成一個新的 Pattern. 如此可進行複雜的條件判斷.

例 如 :

FNR >= 23 && FNR <= 28 { print "     " $0 }

上式利用&& (and) 将兩個 Pattern 求值的結果合并成一個邏輯值.

該式将資料檔案中 第23行 到 28行 向右移5格(先輸出5個空白字元)後輸出.

/2/0{print}

上式利用正規表達式和數值常量0結合的結果合并為一個邏輯值.

該式中非空字元串永遠為真,不管正則結果是真還是假,結果永遠為真,列印檔案所有行,等同于1{print}簡寫為{print}

Pattern1 , Pattern2

遇到這種 Pattern, awk 會設定一個區間的開關,即switch(或flag).

當awk讀入的資料行使得 Pattern1 成立時, awk 會打開(turn on)這 switch.

當awk讀入的資料行使得 Pattern2 成立時, awk 會關上(turn off)這個 switch.

該 Pattern 成立的條件是 :

當這個 switch 被打開(turn on)時 (包括 Pattern1, 或 Pattern2 為真的情況)

可改寫為

FNR == 23 , FNR == 28 { print "     " $0 }

說 明 :

當 FNR >= 23 時, awk 就 turn on 這個 switch; 因為随着資料行的讀入, awk不停的累加 FNR. 當 FNR = 28 時, Pattern2 (FNR == 28) 便成立, 這時 awk 會關閉 switch.

當 switch 打開的期間, awk 會執行  print "     " $0

'/2/,/2/

其實等價于

/2/

說明:

當目前讀入的行即$0中比對到2這個字元,awk就turn on這個switch;從目前讀入的行開始繼續向下讀,直到讀入的行中比對到2這個字元,awk就turn off這個switch.

'/1/,/2/

當目前讀入的行比對到1這個字元,awk就turn on這個switch,從目前讀入的行開始繼續向下讀,直到讀入的行比對到2這個字元,awk就turn off這個switch.

【Actions】

Actions 是由下列指令(statement)所組成 :

· 表達式 ( function calls, assignments..)

· print 表達式清單

· printf( 格式化字元串, 表達式清單)

· if( 表達式 ) 語句 [else 語句]

· while( 表達式 ) 語句

· do 語句 while( 表達式)

· for( 表達式; 表達式; 表達式) 語句

· for( variable in array) 語句

· delete

· break

· continue

· next

· exit [表達式]

繼續閱讀