AWK 實用工具帶有其自己的自包含語言,它不僅是 Linux 中也是任何環境中現有的功能最強大的數據處理引擎之一。這種編程及數據操作語言(其名稱得自於它的創始人 Alfred Aho、Peter Weinberger 和 Brian Kernighan 姓氏的首個字母)的最大功能取決於一個人所擁有的知識。它允許您創建簡短的程序,這些程序讀取輸入文件、為數據排序、處理數據、對輸入執行計算以及生成報表,還有無數其他的功能。
AWK 是什麼? 最簡單地說,AWK 是一種用於處理文本的編程語言工具。AWK 實用工具的語言在很多方面類似於 shell 編程語言,盡管 AWK 具有完全屬於其本身的語法。在最初創造 AWK 時,其目的是用於文本處理,並且這種語言的基礎是,只要在輸入數據中有模式匹配,就執行一系列指令。該實用工具掃描文件中的每一行,查找與命令行中所給定內容相匹配的模式。如果發現匹配內容,則進行下一個編程步驟。如果找不到匹配內容,則繼續處理下一行。 盡管操作可能會很復雜,但命令的語法始終是: awk '{pattern + action}' {filenames} 其中 pattern 表示 AWK 在數據中查找的內容,而 action 是在找到匹配內容時所執行的一系列命令。花括號 ({}) 不需要在程序中始終出現,但它們用於根據特定的模式對一系列指令進行分組。
了解字段 實用工具將每個輸入行分為記錄和字段。記錄是單行的輸入,而每條記錄包含若干字段。默認的字段分隔符是空格或制表符,而記錄的分隔符是換行。雖然在默認情況下將制表符和空格都看作字段分隔符(多個空格仍然作為一個分隔符),但是可以將分隔符從空格改為任何其它字符。 為了進行演示,請查看以下保存為 emp_names 的員工列表文件: 46012 DULANEY EVAN MOBILE AL 46013 DURHAM JEFF MOBILE AL 46015 STEEN BILL MOBILE AL 46017 FELDMAN EVAN MOBILE AL 46018 SWIM STEVE UNKNOWN AL 46019 BOGUE ROBERT PHOENIX AZ 46021 JUNE MICAH PHOENIX AZ 46022 KANE SHERYL UNKNOWN AR 46024 WOOD WILLIAM MUNCIE IN 46026 FERGUS SARAH MUNCIE IN 46027 BUCK SARAH MUNCIE IN 46029 TUTTLE BOB MUNCIE IN 當 AWK 讀取輸入內容時,整條記錄被分配給變量 $0。每個字段以字段分隔符分開,被分配給變量 $1、$2、$3 等等。一行在本質上可以包含無數個字段,通過字段號來訪問每個字段。因此,命令 awk '{print $1,$2,$3,$4,$5}' names 將會產生的打印輸出是 46012 DULANEY EVAN MOBILE AL 46013 DURHAM JEFF MOBILE AL 46015 STEEN BILL MOBILE AL 46017 FELDMAN EVAN MOBILE AL 46018 SWIM STEVE UNKNOWN AL 46019 BOGUE ROBERT PHOENIX AZ 46021 JUNE MICAH PHOENIX AZ 46022 KANE SHERYL UNKNOWN AR 46024 WOOD WILLIAM MUNCIE IN 46026 FERGUS SARAH MUNCIE IN 46027 BUCK SARAH MUNCIE IN 46029 TUTTLE BOB MUNCIE IN 值得注意的一項重要內容是,AWK 解釋由空格分隔的五個字段,但當它打印顯示內容時,在每個字段間只有一個空格。利用為每個字段指定了唯一號碼的功能,您可以選擇只打印特定的字段。例如,只打印每條記錄的姓名時,只需選擇第二個和第三個字段進行打印: $ awk '{print $2,$3}' emp_names DULANEY EVAN DURHAM JEFF STEEN BILL FELDMAN EVAN SWIM STEVE BOGUE ROBERT JUNE MICAH KANE SHERYL WOOD WILLIAM FERGUS SARAH BUCK SARAH TUTTLE BOB $ 您還可以指定按任何順序打印字段,而無論它們在記錄中是如何存在的。因此,只需要顯示姓名字段,並且使其順序顛倒,先顯示名字再顯示姓氏: $ awk '{print $3,$2}' emp_names EVAN DULANEY JEFF DURHAM BILL STEEN EVAN FELDMAN STEVE SWIM ROBERT BOGUE MICAH JUNE SHERYL KANE WILLIAM WOOD SARAH FERGUS SARAH BUCK BOB TUTTLE $
使用模式 通過包含一個必須匹配的模式,您可以選擇只對特定的記錄而不是所有的記錄進行操作。模式匹配的最簡單形式是搜索,其中要匹配的項目被包含在斜線 (/pattern/) 中。例如,只對那些居住在阿拉巴馬州的員工執行前面的操作: $ awk '/AL/ {print $3,$2}' emp_names EVAN DULANEY JEFF DURHAM BILL STEEN EVAN FELDMAN STEVE SWIM $ 如果您不指定要打印的字段,則會打印整個匹配的條目: $ awk '/AL/' emp_names 46012 DULANEY EVAN MOBILE AL 46013 DURHAM JEFF MOBILE AL 46015 STEEN BILL MOBILE AL 46017 FELDMAN EVAN MOBILE AL 46018 SWIM STEVE UNKNOWN AL $ 對同一數據集的多個命令可以用分號 (;) 分隔開。例如,在一行中打印姓名,而在另一行中打印城市和州名: $ awk '/AL/ {print $3,$2 ; print $4,$5}' emp_names EVAN DULANEY MOBILE AL JEFF DURHAM MOBILE AL BILL STEEN MOBILE AL EVAN FELDMAN MOBILE AL STEVE SWIM UNKNOWN AL $ 如果沒有使用分號 (print $3,$2,$4,$5),則會在同一行中顯示所有內容。另一方面,如果分別給出兩個打印語句,則會產生完全不同的結果: $ awk '/AL/ {print $3,$2} {print $4,$5}' emp_names EVAN DULANEY MOBILE AL JEFF DURHAM MOBILE AL BILL STEEN MOBILE AL EVAN FELDMAN MOBILE AL STEVE SWIM UNKNOWN AL PHOENIX AZ PHOENIX AZ UNKNOWN AR MUNCIE IN MUNCIE IN MUNCIE IN MUNCIE IN $ 只有在列表中找到 AL 時才會給出字段三和字段二。但是,字段四和字段五是無條件的,始終打印它們。只有第一組花括號中的命令對前面緊鄰的命令 (/AL/) 起作用。 結果非常不便於閱讀,可以使其稍微更清晰一些。首先,在城市與州之間插入一個空格和逗號。然後,在每兩行顯示之後放置一個空行: $ awk '/AL/ {print $3,$2 ; print $4", "$5"\n"}' emp_names EVAN DULANEY MOBILE, AL JEFF DURHAM MOBILE, AL BILL STEEN MOBILE, AL EVAN FELDMAN MOBILE, AL STEVE SWIM UNKNOWN, AL $ 在第四和第五個字段之間,添加一個逗號和一個空格(在引號之間),在第五個字段後面,打印一個換行符 (\n)。在 AWK 打印語句中還可以使用那些可在 echo 命令中使用的所有特殊字符,包括: \n(換行) \t(制表) \b(退格) \f(進紙) \r(回車) 因此,要讀取全部五個最初由制表符分隔開的字段,並且也利用制表符打印它們,您可以編程如下 $ awk '{print $1"\t"$2"\t"$3"\t"$4"\t"$5}' emp_names 46012 DULANEY EVAN MOBILE AL 46013 DURHAM JEFF MOBILE AL 46015 STEEN BILL MOBILE AL 46017 FELDMAN EVAN MOBILE AL 46018 SWIM STEVE UNKNOWN AL 46019 BOGUE ROBERT PHOENIX AZ 46021 JUNE MICAH PHOENIX AZ 46022 KANE SHERYL UNKNOWN AR 46024 WOOD WILLIAM MUNCIE IN 46026 FERGUS SARAH MUNCIE IN 46027 BUCK SARAH MUNCIE IN 46029 TUTTLE BOB MUNCIE IN $ 通過連續設置多項標准並用管道 () 符號將其分隔開,您可以一次搜索多個模式匹配: $ awk '/ALIN/' emp_names 46012 DULANEY EVAN MOBILE AL 46013 DURHAM JEFF MOBILE AL 46015 STEEN BILL MOBILE AL 46017 FELDMAN EVAN MOBILE AL 46018 SWIM STEVE UNKNOWN AL 46024 WOOD WILLIAM MUNCIE IN 46026 FERGUS SARAH MUNCIE IN 46027 BUCK SARAH MUNCIE IN 46029 TUTTLE BOB MUNCIE IN $ 這樣可找到每個阿拉巴馬州和印第安那州居民的匹配記錄。但是在試圖找出居住在亞利桑那州的人時,出現了一個問題: $ awk '/AR/' emp_names 46019 BOGUE ROBERT PHOENIX AZ 46021 JUNE MICAH PHOENIX AZ 46022 KANE SHERYL UNKNOWN AZ 46026 FERGUS