如何使用 Awk 程式語言編寫指令碼?
Awk 是一種強大的文字處理語言,以其三位最初的作者命名:Alfred Aho、Peter Weinberger 和 Brian Kernighan。它是一種用途廣泛的語言,主要用於模式掃描和處理。Awk 是 Unix 指令碼的核心,通常用於資料提取、報告和資料轉換等任務。
Awk 指令碼編寫速度快,並且在處理中小型任務時效能良好。在本文中,我們將向您介紹使用 Awk 程式語言編寫指令碼的基礎知識。
基本語法
一個 Awk 程式由一系列模式-動作對組成,寫成如下形式:
pattern { action }
這裡,模式是一個條件。如果輸入行與模式匹配,則執行動作。
例如:
awk '/search_pattern/ { print $0 }' file_name
在這個例子中,awk 將在檔案 file_name 中搜索包含 search_pattern 的行,如果匹配,則列印整行($0)。
使用變數
Awk 有一些內建變數,您可以使用它們來格式化輸出。一些最常用的變數包括:
$0 - 整行。
$1, $2, ... - 每個單獨的欄位(預設以空格分隔)。
FS - 欄位分隔符(預設為空格)。
OFS - 輸出欄位分隔符(預設為空格)。
NR - 已處理的記錄數。
NF - 當前記錄中的欄位數。
讓我們來看一個使用其中一些變數的實際例子。假設我們有一個名為 'students.txt' 的文字檔案,其內容如下:
John Doe 18 Jane Smith 19
我們可以使用 awk 分別列印姓名和年齡:
awk '{ print "Name: " $1 " " $2 ", Age: " $3 }' students.txt
輸出將是:
Name: John Doe, Age: 18 Name: Jane Smith, Age: 19
控制流
Awk 還支援常見的控制流機制,如 if、else、while 和 for。以下是一個使用 if 和 else 的示例:
awk '{ if ($3 > 18) print $1 " is an adult"; else print $1 " is a minor"}' students.txt
輸出將是:
John is an adult Jane is a minor
函式
Awk 具有用於字串操作、算術運算和輸入/輸出等的內建函式。您還可以定義自己的函式。
以下是一個使用者定義函式的示例,該函式將溫度從華氏轉換為攝氏:
function toCelsius(fahrenheit) {
return (fahrenheit - 32) * 5/9
}
BEGIN { print "Fahrenheit Celsius" }
{ print $1, toCelsius($1) }
如果我們有一個輸入檔案 'temperatures.txt',其中包含華氏溫度:
32 212
輸出將是:
Fahrenheit Celsius 32 0 212 100
正則表示式
Awk 支援正則表示式語法,可用於模式匹配。以下是一個基本示例,我們將在 'students.txt' 中搜索以字母 'J' 開頭的行:
awk '/^J/ { print $0 }' students.txt
在這種情況下,插入符號 (^) 表示行的開頭。此指令碼將輸出:
John Doe 18 Jane Smith 19
陣列
Awk 支援一維陣列,可用於更復雜的資料操作。讓我們考慮一個我們想要計算 'students.txt' 檔案中年齡出現次數的情況。以下是如何做到這一點:
awk '{ count[$3]++ } END { for (age in count) print age " appears " count[age] " times." }' students.txt
這將輸出:
18 appears 1 times. 19 appears 1 times.
在此指令碼中,count[$3]++ 使用年齡(第三個欄位)作為陣列的鍵,並在每次出現時遞增其值。
高階資料操作
Awk 還提供了一些內建函式來進行更高階的資料操作。例如,它提供了 split() 函式,該函式可以將字串拆分為陣列:
awk '{ split($1, array, ""); print "First letter of the name: " array[1] }' students.txt
此指令碼將輸出:
First letter of the name: J First letter of the name: J
將 Awk 與其他 Unix 命令結合使用
您可以使用管道 (|) 將 Awk 指令碼與其他 Unix 命令結合使用,這使其成為一個更強大的工具:
cat students.txt | awk '{ print $1 }' | sort | uniq
此命令將列印學生的姓名,對其進行排序,然後刪除任何重複項。在這種情況下,輸出將是:
Jane John
在 Awk 中使用指令碼
雖然在終端中直接使用 Awk 對於簡單任務很常見,但對於更復雜的操作,編寫指令碼可能更方便。Awk 指令碼遵循相同的模式-動作結構,但寫在一個單獨的檔案中。
首先,建立一個副檔名為 .awk 的新檔案。指令碼的第一行應該是 shebang 行,指向 Awk 直譯器:
#!/usr/bin/awk -f
讓我們建立一個名為 'students.awk' 的 Awk 指令碼,用於計算學生的平均年齡:
#!/usr/bin/awk -f
BEGIN {
sum = 0
count = 0
}
{
sum += $3
count++
}
END {
print "Average age: " sum/count
}
要執行指令碼,請使用 chmod +x students.awk 使其可執行,然後使用 ./students.awk students.txt 執行它。這將列印:
Average age: 18.5
除錯 Awk 指令碼
由於缺乏內建除錯工具,除錯 Awk 指令碼可能有點棘手。但是,使用 print 語句在指令碼的不同位置顯示變數的值可能會有所幫助。
此外,-W dump-variables[=file] 選項可用於將所有變數和陣列轉儲到檔案中以進行除錯。要使用此選項,您將執行 awk -W dump-variables=dump.txt script.awk。
高階模式匹配
Awk 還支援使用正則表示式的高階模式匹配。例如,您可以使用 ~ 運算子將欄位與正則表示式匹配。
考慮一個 students.txt 檔案,其中包含一個他們正在學習的課程的附加欄位:
John Doe 18 ComputerScience Jane Smith 19 Mathematics
要查詢學習計算機科學的學生,您可以編寫:
awk '$4 ~ /ComputerScience/ { print $1 " " $2 " is studying Computer Science." }' students.txt
這將輸出:
John Doe is studying Computer Science.
結論
Awk 是一個用於在基於 Unix 的系統上進行文字處理的強大工具。它的強大之處在於其簡單性和語法的直接性。無論您是在操作文字還是執行算術計算,Awk 都是您程式設計工具包中一個優秀的工具。
請記住,學習 Awk(或任何語言)的最佳方法是使用它。嘗試建立自己的 Awk 指令碼,從簡單的任務開始,然後隨著您對語言的熟悉程度逐漸轉向更復雜的任務。
資料結構
網路
RDBMS
作業系統
Java
iOS
HTML
CSS
Android
Python
C 程式設計
C++
C#
MongoDB
MySQL
Javascript
PHP