程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> shell編程下的AWK語法小結

shell編程下的AWK語法小結

編輯:關於PHP編程

AWK 實用工具帶有其自己的自包含語言,它是Unix/Linux 中也是任何環境中現有的功能最強大的數據處理引擎之一。這種編程及數據操作語言(其名稱得自於它的創始人 Alfred Aho、Peter Weinberger 和 Brian Kernighan 姓氏的首個字母)的最大功能取決於一個人所擁有的知識。它允許您創建簡短的程序,這些程序讀取輸入文件、為數據排序、處理數據、對輸入執行計算以及生成報表,還有無數其他的功能。
AWK 是什麼? 最簡單地說,AWK 是一種用於處理文本的編程語言工具。AWK 實用工具的語言在很多方面類似於 shell 編程語言,盡管 AWK 具有完全屬於其本身的語法。在最初創造 AWK 時,其目的是用於文本處理,並且這種語言的基礎是,只要在輸入數據中有模式匹配,就執行一系列指令。該實用工具掃描文件中的每一行,查找與命令行中所給定內容相匹配的模式。如果發現匹配內容,則進行下一個編程步驟。如果找不到匹配內容,則繼續處理下一行。 盡管操作可能會很復雜,但命令的語法始終是: awk {pattern + action} 其中 pattern 表示 AWK 在數據中查找的內容,而 action 是在找到匹配內容時所執行的一系列命令。花括號 ({}) 不需要在程序中始終出現,但它們用於根據特定的模式對一系列指令進行分組。 了解字段 實用工具將每個輸入行分為記錄和字段。記錄是單行的輸入,而每條記錄包含若干字段。默認的字段分隔符是空格或制表符,而記錄的分隔符是換行。雖然在默認情況下將制表符和空格都看作字段分隔符(多個空格仍然作為一個分隔符),但是可以將分隔符從空格改為任何其它字符。 為了進行演示,請查看以下保存為 emp_names 的員工列表文件: 46012 DULANEY EVAN MOBILE AL46013 DURHAM JEFF MOBILE AL46015 STEEN BILL MOBILE AL46017 FELDMAN EVAN MOBILE AL46018 SWIM STEVE UNKNOWN AL46019 BOGUE ROBERT PHOENIX AZ46021 JUNE MICAH PHOENIX AZ46022 KANE SHERYL UNKNOWN AR46024 WOOD WILLIAM MUNCIE IN46026 FERGUS SARAH MUNCIE IN46027 BUCK SARAH MUNCIE IN46029 TUTTLE BOB MUNCIE IN當 AWK 讀取輸入內容時,整條記錄被分配給變量 。每個字段以字段分隔符分開,被分配給變量 、、 等等。一行在本質上可以包含無數個字段,通過字段號來訪問每個字段。因此,命令 awk {print ,,,,} names 將會產生的打印輸出是 46012 DULANEY EVAN MOBILE AL46013 DURHAM JEFF MOBILE AL46015 STEEN BILL MOBILE AL46017 FELDMAN EVAN MOBILE AL46018 SWIM STEVE UNKNOWN AL46019 BOGUE ROBERT PHOENIX AZ46021 JUNE MICAH PHOENIX AZ46022 KANE SHERYL UNKNOWN AR46024 WOOD WILLIAM MUNCIE IN46026 FERGUS SARAH MUNCIE IN46027 BUCK SARAH MUNCIE IN46029 TUTTLE BOB MUNCIE IN值得注意的一項重要內容是,AWK 解釋由空格分隔的五個字段,但當它打印顯示內容時,在每個字段間只有一個空格。利用為每個字段指定了唯一號碼的功能,您可以選擇只打印特定的字段。例如,只打印每條記錄的姓名時,只需選擇第二個和第三個字段進行打印: $ awk {print ,} emp_namesDULANEY EVANDURHAM JEFFSTEEN BILLFELDMAN EVANSWIM STEVEBOGUE ROBERTJUNE MICAHKANE SHERYLWOOD WILLIAMFERGUS SARAHBUCK SARAHTUTTLE BOB$您還可以指定按任何順序打印字段,而無論它們在記錄中是如何存在的。因此,只需要顯示姓名字段,並且使其順序顛倒,先顯示名字再顯示姓氏: $ awk {print ,} emp_namesEVAN DULANEYJEFF DURHAMBILL STEENEVAN FELDMANSTEVE SWIMROBERT BOGUEMICAH JUNESHERYL KANEWILLIAM WOODSARAH FERGUSSARAH BUCKBOB TUTTLE$使用模式 通過包含一個必須匹配的模式,您可以選擇只對特定的記錄而不是所有的記錄進行操作。模式匹配的最簡單形式是搜索,其中要匹配的項目被包含在斜線 (/pattern/) 中。例如,只對那些居住在阿拉巴馬州的員工執行前面的操作: $ awk /AL/ {print ,} emp_namesEVAN DULANEYJEFF DURHAMBILL STEENEVAN FELDMANSTEVE SWIM$如果您不指定要打印的字段,則會打印整個匹配的條目: $ awk /AL/ emp_names46012 DULANEY EVAN MOBILE AL46013 DURHAM JEFF MOBILE AL46015 STEEN BILL MOBILE AL46017 FELDMAN EVAN MOBILE AL46018 SWIM STEVE UNKNOWN AL$對同一數據集的多個命令可以用分號 (;) 分隔開。例如,在一行中打印姓名,而在另一行中打印城市和州名: $ awk /AL/ {print , ; print ,} emp_namesEVAN DULANEYMOBILE ALJEFF DURHAMMOBILE ALBILL STEENMOBILE ALEVAN FELDMANMOBILE ALSTEVE SWIMUNKNOWN AL$如果沒有使用分號 (print ,,,),則會在同一行中顯示所有內容。另一方面,如果分別給出兩個打印語句,則會產生完全不同的結果: $ awk /AL/ {print ,} {print ,} emp_namesEVAN DULANEYMOBILE ALJEFF DURHAMMOBILE ALBILL STEENMOBILE ALEVAN FELDMANMOBILE ALSTEVE SWIMUNKNOWN ALPHOENIX AZPHOENIX AZUNKNOWN ARMUNCIE INMUNCIE INMUNCIE INMUNCIE IN$只有在列表中找到 AL 時才會給出字段三和字段二。但是,字段四和字段五是無條件的,始終打印它們。只有第一組花括號中的命令對前面緊鄰的命令 (/AL/) 起作用。 結果非常不便於閱讀,可以使其稍微更清晰一些。首先,在城市與州之間插入一個空格和逗號。然後,在每兩行顯示之後放置一個空行: $ awk /AL/ {print , ; print ", ""n"} emp_namesEVAN DULANEYMOBILE, ALJEFF DURHAMMOBILE, ALBILL STEENMOBILE, ALEVAN FELDMANMOBILE, ALSTEVE SWIMUNKNOWN, AL$在第四和第五個字段之間,添加一個逗號和一個空格(在引號之間),在第五個字段後面,打印一個換行符 (n)。在 AWK 打印語句中還可以使用那些可在 echo 命令中使用的所有特殊字符,包括: n(換行) t(制表) b(退格) f(進紙) r(回車)因此,要讀取全部五個最初由制表符分隔開的字段,並且也利用制表符打印它們,您可以編程如下 $ awk {print "t""t""t""t"} emp_names46012 DULANEY EVAN MOBILE AL46013 DURHAM JEFF MOBILE AL46015 STEEN BILL MOBILE AL46017 FELDMAN EVAN MOBILE AL46018 SWIM STEVE UNKNOWN AL46019 BOGUE ROBERT PHOENIX AZ46021 JUNE MICAH PHOENIX AZ46022 KANE SHERYL UNKNOWN AR46024 WOOD WILLIAM MUNCIE IN46026 FERGUS SARAH MUNCIE IN46027 BUCK SARAH MUNCIE IN46029 TUTTLE BOB MUNCIE IN$通過連續設置多項標准並用管道 (|) 符號將其分隔開,您可以一次搜索多個模式匹配: $ awk /AL|IN/ emp_names46012 DULANEY EVAN MOBILE AL46013 DURHAM JEFF MOBILE AL46015 STEEN BILL MOBILE AL46017 FELDMAN EVAN MOBILE AL46018 SWIM STEVE UNKNOWN AL46024 WOOD WILLIAM MUNCIE IN46026 FERGUS SARAH MUNCIE IN46027 BUCK SARAH MUNCIE IN46029 TUTTLE BOB MUNCIE IN$這樣可找到每個阿拉巴馬州和印第安那州居民的匹配記錄。但是在試圖找出居住在亞利桑那州的人時,出現了一個問題: $ awk /AR/ emp_names46019 BOGUE ROBERT PHOENIX AZ46021 JUNE MICAH PHOENIX AZ46022 KANE SHERYL UNKNOWN AZ46026 FERGUS SARAH MUNCIE IN46027 BUCK SARAH MUNCIE IN$員工 46026 和 46027 沒有住在亞利桑那州;但是他們的名字中包含所搜索的字符序列。切記,當在 AWK 中進行模式匹配時,例如 grep、sed 或者大部分其他 Linux/Unix 命令,將在記錄(行)中的任何位置查找匹配,除非指定進行其他操作。為解決這一問題,必須將搜索與特定字段聯系起來。通過利用代字號 (?) 以及對特定字段的說明,可以達到這一目的,如下例所示: $ awk ? /AR/ emp_names46019 BOGUE ROBERT PHOENIX AZ46021 JUNE MICAH PHOENIX AZ46022 KANE SHERYL UNKNOWN AZ$代字號(表示匹配)的對應符號是一個前面帶有感歎號的代字號 (!?)。這些字符通知程序,如果搜索序列沒有出現在指定字段中,則找出與搜索序列相匹配的所有行: $ awk !? /AR/ names46012 DULANEY EVAN MOBILE AL46013 DURHAM JEFF MOBILE AL46015 STEEN BILL MOBILE AL46017 FELDMAN EVAN MOBILE AL46018 SWIM STEVE UNKNOWN AL46024 WOOD WILLIAM MUNCIE IN46026 FERGUS SARAH MUNCIE IN46027 BUCK SARAH MUNCIE IN46029 TUTTLE BOB MUNCIE IN$在這種情況下,將顯示第五個字段中沒有 AR 的所有行 — 包括兩個 Sarah 條目,這兩個條目確實包含 AR,但卻是在第三個字段而不是第五個字段中。 花括號和字段分隔符 括號字符在 AWK 命令中起著很重要的作用。出現在括號之間的操作指出將要發生什麼以及何時發生。當只使用一對括號時: {print ,} 括號間的所有操作同時發生。當使用多於一對的括號時: {print }{print } 執行第一組命令,在該命令完成後執行第二組命令。注意以下兩列清單的區別: $ awk {print ,} namesEVAN DULANEYJEFF DURHAMBILL STEENEVAN FELDMANSTEVE SWIMROBERT BOGUEMICAH JUNESHERYL KANEWILLIAM WOODSARAH FERGUSSARAH BUCKBOB TUTTLE$$ awk {print }{print } namesEVANDULANEYJEFFDURHAMBILLSTEENEVANFELDMANSTEVESWIMROBERTBOGUEMICAHJUNESHERYLKANEWILLIAMWOODSARAHFERGUSSARAHBUCKBOBTUTTLE$要利用多組括號進行重復查找,執行第一組中的命令直到完成為止;然後處理第二組命令。如果有第三組命令,則在第二組命令完成後執行它,以此類推。在所生成的打印輸出中,有兩個分隔的打印命令,因此先執行第一個命令,隨後執行第二個命令,這樣導致每個條目顯示在兩行而不是一行中。 區分兩個字段的字段分隔符不一定始終是空格;它可以是任何可識別的字符。為進行演示,假定 emp_names 文件利用冒號而不是制表符來分隔字段: $ cat emp_names46012:DULANEY:EVAN:MOBILE:AL46013:DURHAM:JEFF:MOBILE:AL46015:STEEN:BILL:MOBILE:AL46017:FELDMAN:EVAN:MOBILE:AL46018:SWIM:STEVE:UNKNOWN:AL46019:BOGUE:ROBERT:PHOENIX:AZ46021:JUNE:MICAH:PHOENIX:AZ46022:KANE:SHERYL:UNKNOWN:AR46024:WOOD:WILLIAM:MUNCIE:IN4602

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved