我們會用 AWK 來指稱這門_語言_,並用 awk 或 gawk 來指稱解讀 AWK 程式的_執行檔_。
一個 AWK 程式由一組組模式與動作的配對組成
pattern1 { action1 }
pattern2 { action2 }
...
模式可以是對輸入進行比對的正規表示式。也可以是任何結果為 true 或 false 的運算式。
動作是一道或多道 AWK 指令。外面的大括號是必要的。
如果模式的結果為 true,就會執行對應的動作。
AWK 會把輸入解析成一連串的紀錄。每筆紀錄會再切割成零個或多個欄位。
預設行為是:
模式可以省略,此時動作會_對每一筆輸入紀錄_執行。
動作也可以省略,此時預設動作是印出目前的紀錄。
有兩個經常使用的特殊模式。
BEGIN會在讀取任何輸入之前執行對應的動作。END會在讀完所有輸入之後執行對應的動作。你可以用$1、$2、$3等來取用欄位。
目前的紀錄是$0。
說得精確一點,這些其實不算是嚴格的「變數」。$可以視為一種_運算子_,用來取得指定欄位編號的值。我們會在後續的概念中更深入探討。
以下是其他一些常用的內建變數。
RS是輸入的紀錄分隔符。如前所述,它的預設值是換行字元。FS是輸入的欄位分隔符。這些變數通常會設定在BEGIN動作區塊裡。
這些變數會在程式執行期間由 AWK 自動設定。
NF儲存目前紀錄的欄位數量。
$NF。NR儲存目前的紀錄編號。
NR會保存到目前為止已處理的紀錄總數。FNR儲存目前輸入檔案中目前的紀錄編號。
NR == FNR {action}
它的意思是「如果累計的紀錄編號等於目前檔案的紀錄編號」。這只有在_第一個輸入檔_的紀錄中才可能成立。AWK 的真假值判定概念和 C 一樣:
0為假。由於 AWK 是文字處理語言,真假值的概念也延伸到字串。
""為假。AWK 的真假值判定概念和 C 一樣
AWK 於 1970 年代在貝爾實驗室誕生,那裡也正是 C 被發明的地方。C 對 AWK 的語法有很大的影響。
有個奇怪的地方要留意
0為假。"0"卻為真!我們會在後續的概念裡進一步談 AWK 的資料型態。
註解以#字元開頭,一直延伸到該行結尾。
awk
awk可以從檔案或標準輸入讀取輸入。以下這些做法都可以用。
awk '/regex/ {print $1}' file1 file2 ...
awk '/regex/ {print $1}' < file
some_command_here | awk '/regex/ {print $1}'
在類 Unix 系統上,/etc/passwd存放使用者的相關資訊。每個使用者各佔一行,欄位之間以冒號分隔。
如要列出使用者名稱:
awk '
BEGIN { FS = ":" }
{ print $1 }
' /etc/passwd
注意{print $1}這個動作沒有模式,所以每一筆紀錄都會執行它。
如果只想輸出以 bash 作為登入 shell 的使用者,可以這樣寫:
awk '
BEGIN { FS = ":" }
$7 == "/bin/bash" { print $1 }
' /etc/passwd
以下是一些 awk 程式,能和常見的 Unix 指令產生相同結果。
顯示檔案
cat file.txt
awk '1' file.txt
在檔案中搜尋模式
grep 'foo.*bar' file.txt
awk '/foo.*bar/' file.txt
只顯示檔案開頭的幾行
head -n 20 file.txt
awk '
1
NR == 20 {exit}
' file.txt
取代檔案中的文字
sed 's/foo/bar/' file.txt
awk '{sub(/foo/, "bar")};1' file.txt
# or more readably
awk '
{
sub(/foo/, "bar")
print
}
' file.txt