Awk 入門/變數
如前所述,Awk 支援使用者定義的變數和它自己的預定義變數。任何以字母開頭,由字母數字字元或下劃線 (_) 組成的識別符號都可以用作變數名,前提是它不與 Awk 的保留字衝突。顯然,變數名中不允許出現空格;這會造成太多混淆。注意,使用保留字是構建 Awk 程式時的常見錯誤,因此,如果程式在看似無害的單詞上崩潰,請嘗試將其更改為更不尋常的名稱,看看問題是否消失。
無需宣告變數,事實上也無法宣告,雖然在一個複雜的 Awk 程式中,在 BEGIN 子句中初始化變數是一個好主意,以使它們更清晰,並確保它們具有正確的初始值。依賴預設值是任何程式語言中的一個壞習慣,儘管在 Awk 中,所有變數都以零(如果用作數字)或空字串的值開始。Awk 中沒有宣告變數的事實也會導致一些奇怪的錯誤,例如拼錯變數名,並且沒有意識到這已經建立了第二個不同的變數,該變數與程式的其餘部分不同步。
同樣如前所述,Awk 是弱型別的。變數沒有資料型別,因此它們可以用來儲存字串或數值;對變數的字串操作將產生字串結果,數字操作將產生數字結果。如果文字字串看起來不像數字,它在數字操作中將被簡單地視為 0。Awk 有時會因為這個問題而造成混淆,因此程式設計師必須記住這一點,並避免潛在的陷阱。例如
var = 1776var = "1776"
這兩個例子是相同的——它們都將值 1776 載入到名為 var 的變數中。這兩種情況下都可以將其視為計算中的數值,也可以對其執行字串操作。如果 var 載入了以下形式的文字字串
var = "somestring"
可以對其執行字串操作,但它在數字操作中將計算為 0。如果將此示例更改如下
var = somestring
現在,這將始終針對字串和數字操作返回 0——因為 Awk 認為沒有引號的 somestring 是未初始化變數的名稱。順便說一句,可以測試未初始化變數是否為 0
var == 0
如果 var 沒有初始化,則此測試將返回“true”;但是,奇怪的是,嘗試 print 未初始化的變數不會返回任何內容。例如
print something
這隻會列印一個空行,而
something = 0; print something
這將列印一個“0”。
與許多其他語言不同,Awk 字串變數不表示為字元的一維陣列。但是,可以使用 substr() 函式訪問字串中的字元。有關陣列和字串處理函式的更多資訊將在後面介紹。
Awk 的內建變數包括欄位變數——$1、$2、$3 等($0 是整行)——它們將一行文字分解為稱為欄位的單個單詞或片段。很快,我們將看到更高階的 Awk 程式如何操作多行資料,例如郵寄地址列表。
但是,Awk 還有幾個內建變數。其中一些可以透過使用賦值運算子進行更改。例如,編寫 FS=":" 將將欄位分隔符更改為冒號。從那時起,欄位變數將引用當前行中每個冒號分隔的部分。
NR:保持輸入記錄數量的當前計數。請記住,記錄通常是行;Awk 對檔案中每條記錄執行一次模式/動作語句。NF:保持當前輸入記錄中欄位數量的計數。請記住,欄位預設情況下是空格分隔的單詞,但本質上是資料的“列”,如果您的輸入檔案格式類似於表格。可以使用$NF訪問輸入行中的最後一個欄位。FILENAME:包含當前輸入檔案的名稱。FS:包含用於在輸入行上劃分欄位的欄位分隔符字元。預設值為“空格”,即空格和製表符字元。FS可以重新分配給另一個字元(通常在BEGIN中)以更改欄位分隔符。RS:儲存當前記錄分隔符字元。由於預設情況下,輸入行是輸入記錄,因此預設記錄分隔符字元是換行符。透過將FS設定為換行符並將RS設定為空行 (RS=""),您可以處理多行資料。這將用於,例如,地址列表(每個地址佔用多行)。OFS:儲存輸出欄位分隔符,它在 Awk 列印時將欄位分隔開。預設值為空格。只要print有幾個用逗號分隔的引數,它將在每個引數之間列印OFS的值。ORS:儲存輸出記錄分隔符,它在 Awk 列印時將輸出行分隔開。預設值為換行符。print會自動在它要列印的內容的末尾輸出ORS的內容。OFMT:儲存數字輸出的格式。預設格式為“%.6g”,將在討論printf時解釋。ARGC:存在的命令列引數數量。ARGV:命令列引數列表。
順便說一句,值可以載入到欄位變數中;它們不是隻讀的。例如
$2 = "NewText"
這會將輸入行中的第二個文字欄位更改為“NewText”。它不會修改輸入檔案;別擔心。這可以用作對輸入檔案行進行修改的技巧,然後只需使用 print 而不帶任何引數來列印這些行。
再次,所有變數都可以修改,儘管某些內建變數不會產生預期的效果。例如,您可以更改 FILENAME 的值,但它不會載入新檔案。Awk 只是照常繼續,但如果訪問 FILENAME,新值將存在。NR 和 NF 也是如此——更改它們的值會影響您的程式,如果它讀取這些變數,但它不會影響 Awk 的行為。
- 編寫地址簿程式。您需要將
FS設定為換行符,將RS設定為空行。您的程式應該讀取多行輸入並在單行格式中輸出它。 - 編寫一個程式,該程式讀取數字列表並將它們輸出為不同的格式。每個輸入行都應該以逗號或連字元之類的字元開頭,後面跟著空格,然後最多五個數字(空格分隔)。您的程式應該輸出這些數字,並在它們之間使用新的分隔符(在行的開頭給出)。您需要為每一行輸入修改
OFS。
繼續到下一頁,瞭解 Awk 強大的關聯陣列。