1. 程式人生 > >awk字段和引用的分離

awk字段和引用的分離

而不是 esb john linux 定義 pad hapm bottom chap

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]+"查找一到多位數字,隨後跟一個連字符。最後跟一到多位數字。

參考資料:http://www.linuxawk.com/communication/466.html

awk字段和引用的分離