首頁 > 軟體

awk-基本語法知識

2020-06-16 17:23:49
awk 是一門語言,這當之無愧!awk 除了簡單的文字處理功能,awk具有計算機語言所特有的性質,例如變數、判斷、迴圈、甚至陣列。 
 
簡單的功能:
awk 處理文字時,將文字分成一條一條的記錄,awk允許通過匹配程式碼(正則)匹配記錄;每條記錄都包含多個欄位,awk可以修改欄位分隔符來靈活的隔開欄位。它提供了($0,$1...)存取各個欄位。

awk 常被用於處理欄位。所謂欄位,就是文字檔案中,每一行分成許多列,列與列之間用特定的字元隔開。 

awk 命令分三部分: awk 本身 、 awk要執行的命令內容  、awk的輸入檔案。
awk 執行命令時,依次讀取每一行,將命令應用到每一行。  
  - print 和 print $0 行為完全相同,都是列印一整行!
-F 引數設定的是awk的初始化變數FS,FS控制著awk的欄位分隔符,預設情況下是空白字元
 
awk 支援設定多個欄位分隔符,甚至用正規表示式來設定。
   eg.  awk -F"[t ]+"  // 表示此分隔符匹配一個或多個製表符或空格符 
awk讀取標准輸入。
 
 
AWK的程式碼結構:
   awk預設對每一個輸入行執行一段程式碼塊。
   awk的執行可看成3部分:處理輸入前的初始化(BEGIN{}程式碼塊)、處理輸入過程({}程式碼塊集合)、處理完所有輸入後的掃尾工作(END{}程式碼塊)。
 
   BEGIN程式碼塊,主要完成awk部分引數的初始化操作!
   核心處理輸入的過程:執行體
   END程式碼塊,是在所有輸入都處理完成後awk才去執行的程式碼!
   
  - BEGIN 程式碼塊
   格式:BEGIN標籤加上{}。
   在這個程式碼塊中完成一些變數的初始化操作,只在初始化時被執行一次。
eg.
   awk定義FS變數為欄位分隔符,在命令列 -F引數用於指定欄位分割符,在BEGIN程式碼段中這樣寫:
 fs.awk  // awk 指令碼,-f 引數參照指令碼到awk命令中
  1. BEGIN{
  2.   FS=":"  // 將冒號賦給FS變數,改變欄位分隔符
  3. } 
  4. {
  5. print "USER: " $1 "tSHELL: " $7
  6. }
  1. head -n10 /etc/passwd |awk -f fs.awk
還可以在命令列直接初始化:
  1.   awk 'BEGIN{FS=":"}{print "USER: " $1 "tSHELL: " $7}'
 
-F 和 FS 都可以改變欄位分隔符,FS適用於awk指令碼比較複雜的時候.
 
 
  - END 程式碼塊:
   格式: END{}
   所有輸入處理完成後才去執行!僅僅執行一次!
   END程式碼塊中,awk指令碼可以執行一些類似於統計資料、列印輸出之類的操作。
eg.
  search.awk
  1. BEGIN{ # 初始化資訊,便於閱讀
  2.   print "How many prople with nologin?"
  3. }
  4. /nologin/{++adder} # 核心awk處理過程
  5. END{ # 掃尾工作,列印結果
  6.   print "'nologin' appears "  adder " times."
  7. }
  1. awk -f search.awk /etc/passwd
 
 
  - awk的模式匹配
  針對BEGIN和END之間的第二部分的核心處理過程而言,只對匹配上的資料做處理!
語法: 
     /正規表示式/ {匹配後的操作}
 awk首先用正規表示式去匹配資料記錄,如果匹配上,才執行後面{}內的操作。
eg.1 
  1. awk '/^$/{print "This is an empty line."}'/etc/inittab # 匹配空行一次執行一次輸出
eg.2
shell_recorder.wak
  1. BEGIN{
  2.   print "SHELL USAGE:"
  3. }
  4. /bash/{++bash} //
  5. /nologin/{++nologin}
  6. END{
  7.   print "We have " bash " bash users."
  8.   print "We have " nologin " nologin users."  
  9. }
  1. awk -f shell_recorder.awk /etc/passwd
 
 
awk變數
  有兩種: 使用者自定義變數 、內建變數
     - awk和絕大多數指令碼語言一樣,變數使用無需先宣告,awk會在第一次使用該變數的時候自動建立變數。
     - awk的變數建立時初始值都是空字串,但是在需要數值時,它會被視為0。即awk會自動將字串轉換為數值進行計算。
  在這一點上,awk的行為和shell指令碼是一樣的。大多數指令碼是語言的行為都是這樣:變數值儲存字串,當需要時再轉換為為其他型別。
   
 命名規則:
   awk的變數名必須以ASCII字母下劃線開始,然後選擇性的接上字母、數位、下劃線。
     - 如果用正規表示式來匹配變數名的話,awk的變數名必須匹配[A-Za-z_][A-Za-z_0-9]*
   命名建議: 區域性變數小寫,全域性變數第一個字母大寫,內建變數全部大寫
 
awk 的常見內建變數 
  F-field欄位,域  R-record記錄   S-sign符號  N-number數位
          變數             說明
     FILENAME     當前輸入檔案的名稱
     FNR     當前輸入檔案的記錄數
     NR     工作中的記錄數(行數)
     NF     一條記錄的欄位數(列數)
    FS      欄位分隔符(支援正則),預設空格
     OFS      輸出欄位分隔符
     RS      輸入記錄分隔符,預設換行
     ORS      輸出記錄分隔符

awk陣列
   和awk變數一樣,無需宣告就能使用。
 命名規則:和變數名的命名規則相同:[a-zA-Z_][a-zA-Z_0-9]*
 陣列元素的參照:
    awk支援在陣列名之後,以方括號將任意數位或字串表示式擴起來作為參照陣列的下標(索引)。其他語言要求陣列的下標必須是數位。
 eg.
   site[google] = "http://www.google.com"
   site[yahoo] = "http://yahoo.com"
 (類似於鍵值對的形式,key是下標,value是陣列元素)
 
awk這種能以任意值作為陣列的索引(下標)的陣列,稱為關聯陣列,因為他們的名稱是與值相關聯的。
 
 - awk 支援陣列的查詢、插入、刪除操作。
 - awk陣列的儲存空間在參照新元素時會自動增長。
 - awk陣列的儲存空間是稀疏的,插入了第一個元素array[1]後,可直接插入array[1000],不用填滿2-999之間的陣列元素。
 - awk陣列的元素值可以為任意型別,無型別限制。
總計:awk陣列更像是一系列鍵值對的集合,只不過打上了陣列的標籤。
 
陣列的元素的刪除:
     delete array[index] //刪除陣列的某一個元素
     delete array //刪除陣列所有元素
 
系統環境變數
   awk支援存取linux系統環境變數,通過ENVIRON陣列
 eg.
  awk 'BEGIN{print ENVIRON["HOME"]; print ENVIRON["PATH"]}'
   // 有兩個索引是:ENVIRON["HOME"]、ENVIRON["HOME"]。
awk在啟動時會從系統讀取環境變數對陣列ENVIRON進行初始化,可以對這個陣列進行加入、刪除以及修改。
 
算術運算和運算子
  - 算術運算
  awk中直接進行算術運算,
     支援直接進行算術運算的運算子只有:  +(加) -(減) *(乘) /() %(取模、求餘) ^(冪次方),
例如:
  1. awk 'BEGIN {print "(3+2)*7=" (3+2)*7}'
  2. (3+2)*7=35
  3. awk 'BEGIN {print "3^10=" 3^10}'
  4. 3^10=59049
 
 % 是取模運算,表示式 x%y 中,運算結果是x%y的餘數。當x能被y整除時,結果為0。
例如:判斷閏年
year.txt
  1. 1936圖靈提出人類歷史上第一個人工智慧的概念
  2. 1946世界上第一台計算機"埃尼阿克(ENIAC)"在美國賓西法尼亞大學誕生
  3. 1956第二代計算機產生
  4. 1969Ken.ThompsoDernis.Ritchie發布第一版Unix
  5. 1979 AT&T從各大學收回Unix版權,此後誕生了System V BSD 兩個版本線的Unix作業系統
  6. 1983RichardStallman建立GNU(GNU is not Unix.),1983-1991GNU三大軟體:Bash shellgccemacs.
  7. 1991LinusTorvalds發布Linux核心
  8. 1994Lins加入GNU,GNU系列軟體與Linux核心結合,退出linus's minix,簡稱Linux.
 
leap.awk
  1. # awk 指令碼求閏年
  2. BEGIN {
  3. print "Pick leap years:"
  4. }
  5. {
  6. # $1為記錄的第一個欄位
  7. year=$1
  8. if(( year %4==0&& year %100!=0)||year %400==0)
  9. print year "is a leap year."
  10. else
  11. print year "is not a leap year."
  12. }
  13. END {
  14. print "Checking is over."
  15. }
 awk -f leap.awk year.txt
  1. Pick leap years:
  2. 1936is a leap year.
  3. 1946is not a leap year.
  4. 1956is a leap year.
  5. 1969is not a leap year.
  6. 1979is not a leap year.
  7. 1983is not a leap year.
  8. 1991is not a leap year.
  9. 1994is not a leap year.
  10. 1995is not a leap year.
  11. 2016is a leap year.
  12. Checking is over.
 
  - awk運算子
  1.  =+=-=*=/=^=**=     賦值 # **= 等價於^=
  2.  ?:                       c條件表示式 # 三目運算子,用法:x>y?x:y 若x>y,則返回x,否則,返回y
  3.  ||                       邏輯或  
  4.  &&                       邏輯與
  5.  ~  ~!                    匹配正規表示式不匹配正規表示式
  6. <<=>>=!===           關係運算子
  7. 空格                      連線
  8. +-                        
  9. */%                     求餘
  10. ^                         求冪
  11. ++--                     自加自減
  12. $                         參照欄位
  13. in                        陣列成員
  14. +-!                     一元加、減和邏輯非

Linux常用命令之awk http://www.linuxidc.com/Linux/2016-09/135046.htm

Linux系統之文字格式化工具awk http://www.linuxidc.com/Linux/2016-02/128150.htm

AWK簡介及使用範例 http://www.linuxidc.com/Linux/2013-12/93519.htm

Linux awk文字分析工具 http://www.linuxidc.com/Linux/2015-12/126217.htm

Linux文字處理工具之awk  http://www.linuxidc.com/Linux/2015-01/111437.htm

如何在Linux中使用awk命令 http://www.linuxidc.com/Linux/2014-10/107542.htm

文字分析工具-awk  http://www.linuxidc.com/Linux/2014-12/110939.htm

AWK入門基礎教學  http://www.linuxidc.com/Linux/2016-12/138138.htm

使用awk格式化輸出文字 http://www.linuxidc.com/Linux/2016-04/130193.htm

本文永久更新連結地址http://www.linuxidc.com/Linux/2017-01/139369.htm


IT145.com E-mail:sddin#qq.com