awk使用字段操作符$來指定字段。在該操作符後面跟著一個數字或變量,用於標識字段的位置。"$1" 表示第一個字段, "$2" 表示第二個字段等等。"$0 "表示整個輸入記錄。下面的例子顯示了第一個字段是姓,第二個字段是名字,後面是電話號碼。
$ awk '{ print $2,$1,$3 }' names
Robinson John 666-555-1111
$1表示名字, $2表示姓,而$3表示電話號碼。Print語句中分隔每個參數的逗號使得輸入的各值之間有一個空格(隨後,我們將討論輸出字段分隔符(OFS) ,它的值中輸出的逗號默認為空格)。在這個例子中,一個輸入行包含3個字段:在名字和姓之間有一個空格,在姓和電話號碼之間有一個制表符。如果想將姓和名字結合起來作為一個字段,可以通過顯式地指定字段分隔符走的只識別制表符。這樣, awk將只識別該記錄中的兩個字段。
可以用任何計算值為整數的表達式來表示一個字段,而不只是用數字和變量。
$ echo a b c d | awk 'BEGIN { one = 1; two = 2 }
> { print $(one + two) }'
C
可以在命令行中使用-F選項改變字段的分隔符。下面的例子將字段分隔符修改為制表符。
$ awk -F"\t" '{ print $2 }' names
666-555-1111
"\t" 是表示一個實際的制表符的轉義序列,它應由單引號或雙引號包圍著。下面兩個地址記錄中的字段是由逗號分隔的。
$ cat names
John Robinson, Koren Inc.,978 4th Ave.,Boston,MA 01760,696-0987
Phyllis Chapman, GVE Corp.,34 Sea Drive, Amesbury,MA 01881,879-0900
$ cat blocklist.awk
# blocklist.awk -用塊格式打印姓名和地址
# 輸入文件一名字、公司、街道、城市、州和郵編、電話
{ print "" # output blank line
print $1 # name
print $2 # company
print $3 # street
print $4, $5 # city, state zip
}
第一個print語句指定一個空串("") (記住print 本身輸出當前行)。這種安排使得在報告中的記錄由空格隔開。我們可以執行這個腳本並使用下面的命令指定字段分隔符為逗號:
$ awk -F,-f blocklist.awk names
John Robinson
Koren Inc.
978 4th Ave.
Boston MA 01760
Phyllis Chapman
GVE Corp.
34 Sea Drive
Amesbury MA 01881
在腳本中指定域分隔符是一個好的習慣並且是非常方便的。可以通過定義系統變量FS來改變字段分隔符。因為這個必須在讀取第一行之前執行,所以必須在由BEGIN規則控制的操作中指定這個變量。
BEGIN { FS="," }
我們程序中使用它來打印出姓名和電話號碼。
$cat phonelist.awk
# phonelist.awk -打印姓名和電話號碼
# 輸入文件一名字、公司、街道、城市、州和郵編、電話
BEGIN { FS = "," } #用逗號分割字段
{ print $1 ", " $6 }
注意,我們在腳本中使用空行未改善可讀性。在print語句的兩個輸出字段之間插入逗號和一個空格。這個程序腳本可以通過以下命令行來執行:
$ awk -f phonelist.awk names
John Robinson, 696-0987
Phyllis Chapman, 879-0900
這些給了你一個關於如何使用awk來處理可識別的結構化數據的基本概念。這個程序腳本用來輸出所有的輸入行,但我們可以編寫匹配規則來修改這個操作符使得只打印出特定的名字或地址。因此,如果我們有一個長的名字列表,我們可以僅選擇居住在特定州的人名。我們可以編寫為:
/MA/ {print $1 ", " $6}
這裡的MA於馬薩諸塞州郵政局的縮寫相匹配。然而,MA也可能為一個公司的名字或其他地方的名字相匹配,其中在這些公司的名字或其他地方的名字中包含字母"MA" .我們可以測試匹配指定的字段。使用(~) 操作符可以測試一個字段的正則表達式:
$5 ~ /MA/{ print $1 ", " $6 }
可以使用組合符號(!~)來反轉這個規則的意義。
$5 !~ /MA/ { print $1 ", " $6 }
這個規則將與所有其第五個字段不包含"MA"的記錄相匹配。一個更有挑戰性的模式匹配是僅與長途電話號碼相匹配。下面的正則表達式查找一個區域代碼。
$6 ~ /1?(-|□)?\(?[0-9]+\)?(□|-)?[0-9]+-[0-9]+/
這個規則和下列的形式相匹配:
707-724-0000
(707) 724-0000
(707)724-0000
1-707-724-0000
1 707-724-0000
1 (707)724-0000
這個正則表達式可以分段進行解釋。"1?"表示出現零個或一個1; "(-|□)?"表示在隨後的位置上查找一個連字符或一個空格,或什麼也沒有; "\(?"表示查找零個或一個左括號;反斜槓能夠防止將"("解釋為用於分組的元字符; "[0-9]+"表示查找一個或多個數字;注意我們采用了簡便的方法,僅指定一到多位數字,而不是精確地指定3位數字。在隨後的位置,我們查找一個可選的右括號,接著查找一個空格或一個連字符,或什麼也沒有。然後用" [0~9]+"查找一到多位數字,隨後跟一個連字符,最後跟一到多位數字。
--------------------------------------分割線 --------------------------------------
AWK簡介及使用實例 http://www.linuxidc.com/Linux/2013-12/93519.htm
AWK 簡介和例子 http://www.linuxidc.com/Linux/2012-12/75441.htm
Shell腳本之AWK文本編輯器語法 http://www.linuxidc.com/Linux/2013-11/92787.htm
正則表達式中AWK的學習和使用 http://www.linuxidc.com/Linux/2013-10/91892.htm
文本數據處理之AWK 圖解 http://www.linuxidc.com/Linux/2013-09/89589.htm
如何在Linux中使用awk命令 http://www.linuxidc.com/Linux/2014-10/107542.htm
文本分析工具-awk http://www.linuxidc.com/Linux/2014-12/110939.htm
--------------------------------------分割線 --------------------------------------