處理 Multi-line 記錄
AWK每次從資料檔中只讀取一筆Record, 進行處理. AWK係依照
其內建變數 RS(Record Separator) 的定義將檔案中的資料分隔成
一筆一筆的Record.
RS 的預設值是 "\n"(跳行符號), 故平常AWK中一行資料就是一筆
Record.
但有些檔案中一筆Record涵蓋了數行資料, 這種情況下不能再以
"\n" 來分隔Records. 最常使用的方法是相鄰的Records之間改以
一個空白行 來隔開.
在AWK程式中, 令 RS = ""(空字串)後, AWK把會空白行當成來檔案
中Record的分隔符號. 顯然AWK對 RS = "" 另有解釋方式,簡略描述
如下, 當 RS = "" 時 :
- 數個併鄰的空白行, AWK僅視成一個單一的Record Saparator.
(AWK不會於兩個緊併的空白行之間讀取一筆空的Record)
- AWK會略過(skip)檔首或檔末的空白行. 故不會因為檔首或檔末
的空白行,造成AWK多讀入了二筆空的資料.
請觀察下例,首先建立一個資料檔 week.rpt如下:
張長弓
GNUPLOT 入門
吳國強
Latex 簡介
VAST-2 使用手冊
mathematica 入門
李小華
AWK Tutorial Guide
Regular Expression
該檔案檔首有數列空白行, 各筆Record之間使用一個或數個空白行
隔開. 讀者請細心觀察, 當 RS = "" 時, AWK讀取該資料檔之方式.
編輯一個AWK程式檔案 make_report如下:
awk '
BEGIN {
FS = "\n"
RS = ""
split( "一. 二. 三. 四. 五. 六. 七. 八. 九.", C\_Number, " " )
}
{
printf("\n%s 報告人 : %s \n",C_Number[NR],$1)
for( i=2; i { >}= NF; i++)
printf(" %d. %s\n", i-1, $i)
}
' $
執行
$ make_report week.rpt
螢幕產生結果如下:
一. 報告人 : 張長弓
1. GNUPLOT 入門
二. 報告人 : 吳國強
1. Latex 簡介
2. VAST-2 使用手冊
3. mathematica 入門
三. 報告人 : 李小華
1. AWK Tutorial Guide
2. Regular Expression
說明:
- 本程式同時也改變欄位分隔字元( FS= "\n"), 如此一筆資料
中的每一行都是一個field. 例如 : AWK讀入的第一筆 Record 為
張長弓
GNUPLOT 入門
其中 $1 指的是"張長弓", $2 指的是"GNUPLOT 入門"
- 上式中的C\_Number[ ]是一個陣列(array), 用以記錄中文數字.
例如 : C\_Number[1] = "一", C\_Number[2] = "二"
這過程使用AWK字串函數 split( ) 來把中文數字放進陣列
Number[ ]中. 函數 split( )用法如下 :
split( 原字串, 陣列名稱, 分隔字元(field separator) ) :
AWK將依所指定的分隔字元(field separator)分隔原字串成一個個
的欄位(field), 並以指定的 陣列 記錄各個被分隔的欄位