如何使用 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 指令碼,從簡單的任務開始,然後隨著您對語言的熟悉程度逐漸轉向更復雜的任務。

更新於:2023年7月17日

111 次瀏覽

開啟你的 職業生涯

透過完成課程獲得認證

開始學習
廣告

© . All rights reserved.