Awk 入門/Nawk
外觀
< Awk 入門
Awk 的最初版本是在 1977 年開發的。它針對快速編寫“單行程式”或簡短、快速、簡陋的程式進行了最佳化。然而,一些使用者非常喜歡 Awk,以至於他們將它用於更復雜的任務。引用語言作者的話:“當我們遇到一個不適合在一頁上顯示的程式時,我們感到震驚和驚訝。”一些使用者將 Awk 視為他們主要程式設計工具,事實上許多人學習程式設計就是使用 Awk。
在作者克服了最初的震驚後,他們決定接受這一事實,並增強 Awk,使其成為更好的通用程式設計工具。新版本的 Awk 於 1985 年釋出。新版本通常(如果不總是)被稱為 Nawk(“新 Awk”),以區別於舊版本。
- Nawk 包含了一些重大改進。最重要的改進是使用者可以定義自己的函式。例如,以下 Nawk 程式實現了“signum”函式
{for (field=1; field<=NF; ++field) {print signum($field)}};
function signum(n) {
if (n<0)
return -1
else if (n==0) return 0
else
return 1}
函式宣告可以放置在程式中的任何地方,只要匹配-操作子句可以放置的地方都可以。所有引數都是函式的區域性變數。區域性變數可以在函式內部定義。
- 第二個改進是一個新函式“getline”,它允許從除了在呼叫時指定的命令列中的檔案以外的檔案中輸入(以及從管道輸入)。“Getline”可以以多種方式使用
getline Loads $0 from current input. getline myvar Loads "myvar" from current input. getline myfile Loads $0 from "myfile". getline myvar myfile Loads "myvar" from "myfile". command | getline Loads $0 from output of "command". command | getline myvar Loads "myvar" from output of "command".
- 一個相關的函式“close”允許關閉檔案,以便再次從開頭讀取
close("myfile")
- 一個新函式“system”允許 Awk 程式呼叫系統命令
system("rm myfile")
- 命令列引數可以使用兩個新的預定義變數 ARGC 和 ARGV 來解釋,這是一種對 C 程式設計師來說立即熟悉的機制。ARGC(“引數計數”)給出命令列元素的數量,而 ARGV(“引數向量”)是一個數組,其條目分別儲存元素。
- 存在一個新的條件賦值表示式,稱為“?:”,其用法如下
status = (condition == "green")? "go" : "stop"
這轉換為
if (condition=="green") {status = "go"} else {status = "stop"}
這種結構也應該對 C 程式設計師來說很熟悉。
- 有新的數學函式,例如三角函式和隨機數函式
sin(x) Sine, with x in radians. cos(x) Cosine, with x in radians. atan2(y,z) Arctangent of y/x, in range -PI to PI. rand() Random number, with 0 <= number < 1. srand() Seed for random-number generator.
- 有新的字串函式,例如匹配函式和替換函式
- match(<目標字串>,<搜尋字串>)
在目標字串中搜索搜尋字串;如果未匹配,則返回 0,如果匹配,則返回搜尋字串的起始索引。還將內建變數 RSTART 設定為起始索引,並將內建變數 RLENGTH 設定為匹配字串的長度。 - sub(<正則表示式>,<替換字串>)
在 $0 中搜索正則表示式的第一個匹配項並替換替換字串。該函式返回所做替換的數量,就像其他替換函式一樣。 - sub(<正則表示式>,<替換字串>,<目標字串>)
在目標字串中搜索正則表示式的第一個匹配項並替換替換字串。 - gsub(<正則表示式>,<替換字串>)
在 $0 中搜索正則表示式的所有匹配項並替換替換字串。 - sub(<正則表示式>,<替換字串>,<目標字串>)
在目標字串中搜索正則表示式的所有匹配項並替換替換字串。
- match(<目標字串>,<搜尋字串>)
- 存在一種處理多維陣列的機制。例如,以下程式建立並列印一個矩陣,然後列印該矩陣的轉置
BEGIN {count = 1;
for (row = 1; row <= 5; ++row) {
for (col = 1; col <= 3; ++col) {
printf("%4d",count);
array[row,col] = count++; }
printf("\n"); }
printf("\n");
for (col = 1; col <= 3; ++col) {
for (row = 1; row <= 5; ++row) {
printf("%4d",array[row,col]); }
printf("\n"); }
exit; }
這會產生
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 4 7 10 13 2 5 8 11 14 3 6 9 12 15
Nawk 還包含一個新的“delete”函式,它刪除陣列元素
delete(array[count])
- 字元可以表示為八進位制程式碼。例如,“\033”可用於定義“轉義”字元。
- 一個新的內建變數 FNR 會跟蹤當前檔案的記錄號,而不是 NR,NR 會跟蹤當前輸入行的記錄號,而不管有多少檔案貢獻了該輸入。它的行為與 NR 完全相同。
- 雖然 Nawk 確實有一些有用的改進,但它們通常旨在支援複雜程式的開發。我的感覺是,對於除了最專注的 Awk 使用者之外的所有使用者來說,Nawk 都過於複雜,而且無論如何都需要一個單獨的文件才能充分說明其功能。那些想要了解有關 Nawk 更多資訊的人,可以閱讀 Aho/Weinberger/Kernighan 撰寫的《AWK 程式語言》。這本簡短、簡潔、詳細的書籍概述了 Nawk 的功能,並提供了使用它的複雜示例。