歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux綜合 >> Linux資訊 >> 更多Linux >> AWK:Linux 管理員的智能工具包

AWK:Linux 管理員的智能工具包

日期:2017/2/27 9:26:31   编辑:更多Linux
  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




Copyright © Linux教程網 All Rights Reserved