awk學習筆記

    awk是一種模式掃描和處理工具,相對于grep的查找,sed的編輯,它在對數據進行分析生成報表時顯得尤為強大。awk通過逐行遍歷一個或多個文件的方式,查找模式匹配到的行,而后以指定的分隔符(缺省為空格)進行切片,然后針對切片數據進行處理和分析。事實上,gawk有自己的語言,其本身就相當于一個解釋器,允許用戶創建簡短的程序讀取輸入文件,對輸入數據執行排序、計算以及生成報表操作,甚至可以類似bash shell實現諸如循環、數組、條件判斷、函數、變量等功能,進而完成更為復雜的數據分析處理任務。

    Gawk

    gawk(GNU awk)是UNIX awk的GNU版,為方便linux用戶使用,通常將/bin/awk以符號鏈接方式鏈接到/bin/gawk,以迎合用戶的使用習慣。(下文有提到gawk的地方均以awk代替)

    awk的使用方式

       1、命令行方式

          awk [-F field-separator] ‘COMMAND’inputfiles

         //其中COMMAND是awk的執行命令,用來處理數據,[-F field-separator]是可選選項,inputfiles是待處理文件。

         //awk使用中,需要處理的文件,逐行使用分隔符分割成若干個字段,稱之為域,分隔符默認是空格,可使用-F選項來指定分隔符

       2、shell腳本模式

          將所需執行的awk命令插入awk腳本文件,然后在首行設置命令解釋器為#!/bin/awk,通過鍵入腳本名的方式調用。

       3、所有awk命令寫入到一個單獨的文件,當處理同一類文件需求時,使用awk -f awk-script inputfiles調用之,其中awk-script指awk腳本。

    awk的基本語法    

       awk [OPTION] 'program' FILE1 FILE2…

       program:PATTERN{ACTION STATEMENT} //program由語句組成,各語句之間使用;隔開,整個program要用單引號引起來

       OPTION:選項 

             -F:指定分割符

                例,指定分隔符為“:”,打印出系統上各用戶名和morenshell

                # awk -F: '{print $1,$7}' /etc/passwd

               blob.png

             -v:指定變量

                例,通過-v選項指定變量a=hello awk 然后將其打印出來

                # awk -v a="hello awk" '{print a}'

               blob.png

               另外,也可以通過特殊模式BEGIN(模式下述)來指定變量,如上例,也可以這樣寫

               # awk 'BEGIN{a="hello awk"}{print a}'

               blob.png

             -f:指定腳本文件

    awk變量

       awk的變量,可分類為內置變量和自定義變量

       1、內置變量

         blob.png

       2、自定義變量

         自定義變量有兩種方式(上文基本語法中已有示例,此處不再贅述),但是,在腳本中仍然可以聲明變量。

         (1)、awk -v VARIABLE_NAME VARIABLE_VALUE 'program' inputfiles 

         (2)、awk 'BEGIN{VARIABLE_NAME VARIABLE_VALUE}ACTION STATEMENT}' inputfiles  

       3、變量使用示例

         (1)、FS輸入分隔符,默認為空格

           例如,默認分隔符使用awk提取/etc/inittab中的“#”,如下圖可以看到,如果以空格分割,第一個域即為#(忽略最后一行)

           blob.png

           # awk '{print $1}' /etc/inittab //效果如下(最后一行請忽略) 

           blob.png

           以“:”為分隔符,提取系統中用戶名以及用戶默認

           # awk -v FS=":" '{print $1,$7}' /etc/passwd

           blob.png

         (2)、輸出分隔符,默認為空格(如上圖上例顯示結果),接上例,以:為輸出分隔符顯示輸出結果

           # awk -v FS=":" -v OFS=":" '{print $1,$7}' /etc/passwd 

           blob.png

         (3)、NR和FNR

           顯示/etc/{inittab,passwd}所有內容以及行數

           # awk '{print NR,$0}' /etc/{inittab,passwd}//看下圖,行數不分開計數

           blob.png

           # awk '{print FNR,$0}' /etc/{inittab,passwd}//看下圖,使用FNR單獨計數行數

           blob.png

           # awk 'BEGIN{print "filename","alone_lines","unit_lines"}{print FILENAME,NR,FNR}' /etc/{passwd,inittab,group}//還可以這樣寫來分別顯示總行號和單獨行號,此處不再貼圖

         (4)、ARGC顯示參數個數

           # awk -F: '{print $1}END{print ARGC}' /etc/passwd //如下圖,顯示參數為二(經驗證,貌似program也被識別成為一個參數,再加上后面的文件故為2個參數?) 

           blob.png

    awk的模式

       1、Regular Expression 正則表達式

         如其名,使用正則表達式匹配模式,在需要注意的是,在awk中使用正則表達式,匹配字符串要使用雙斜線括起來,而后匹配到的行將被切片并分析處理,反之將略過。

       取出/etc/passwd中包含root的行并打印出用戶名和默認shell

       # awk -F: ‘/root/ {print $1,$7}' /etc/passwd 

       blob.png

       2、Expression 表達式,當表達式的值為真(非零或非空)的行被匹配,僅處理匹配到的行

       # awk -F: '$3>=500{print $1,$2,$3}' /etc/passwd 

       blob.png

       在此列出awk的常用操作符  

      blob.png

      blob.png

      如果模式自身是=,要寫為/=/

     blob.png

     blob.png

     blob.png

     條件表達式:

       selector?if-true-express:if-false-express 只能是表達式不能使語句

       條件表達式中,“:”兩側僅允許使用表達式而不能使用語句

       例

       # awk -F: '$3>=500?utype="common user":utype="admin or system user"{print $1 "is" utype} /etc/passwd 

       blob.png

       3、range行范圍,有兩種方式來定義此范圍

        (1)、pattern1,pattern2

        從匹配到pattern1的行開始到匹配到pattern2的行為知,此范圍的行被awk action處理

        # awk 'NR==1,NR==10{print $1,$3,$7} /etc/passwd 

        blob.png  

       4、特殊模式BEGIN和END

      (1)、BEGIN在讀取任何輸入之前執行一次語句

        # awk 'BEGIN{FS=":";OFS=":"}/root/{print $1,$3,$7} /etc/passwd 

       blob.png

      (2)、END在讀取所有輸入之后執行一次語句 

       # awk 'BEGIN{FS=":";OFS=":"}/root/{print $1,$3,$7}END{print "The end!"}' /etc/passwd

       blob.png

       5、空模式

         如果不指定模式則匹配文件中的所有行

    awk重定向       

       1、輸出重定向

         awk可以使用shell的重定向符重定向輸出,同樣>代表覆蓋式輸出,>>代表追加。

         覆蓋式重定向

         blob.png

         追加重定向效果

         blob.png

       2、輸入重定向

        輸入重定向需用到getline函數。getline從標準輸入、管道或者當前正在處理的文件之外的其他輸入文件獲得輸入。它負責從輸入獲得下一行的內容,并給NF,NR和FNR等內建變量賦值。如果得到一條記錄,getline函數返回1,如果到達文件的末尾就返回0,如果出現錯誤,例如打開文件失敗,就返回-1,可以結合到while等流控制語句使用。 

       通過例子說明輸入重定向用法

       (1)、awk 'BEGIN{"date" | getline d; print d}'

        blob.png

         getling函數讀取date命令的輸出結果并將其賦值給自定義變量d,然后打印變量d

       (2)、awk 'BEGIN{"date" | getline d; split(d,mon); print mon[3]}'

        blob.png

        getine函數讀取date命令輸出的結果并賦值給自定義變量d,split函數將變量d轉化為數組mon,然后打印數組mon的第三個元素。

       (3)、awk 'BEGIN{while("ls" | getline) print}'

        blob.png

       getline函數讀取ls命令的輸出結果而后打印顯示

    awk之print和printf

       1、print

       用法:print item1,item2….

       要點:

        (1)、各item之間使用,號隔開,輸出時默認以空格分隔

        (2)、輸出的item可以是字符串或數值、當前分隔出來的域(字段,如$1)、變量或awk的表達式,數值會隱式轉換為字符串輸出。

        (3)、print后面的item項可以省略,此時相當于打印$0即整行內容;print ""表示打印空白行。

           例:

           # awk 'BEGIN{print "line1","line2","line3"}'

           blob.png

           # awk -F: '{print $1,$3,$7}' /etc/passwd 

           blob.png

       2、printf

        用來格式話打印輸出內容

        (1)、格式:

         printf format,item1,ietm2,…

        (2)、要點

          printf需要指定format;

          format用于指定后面每個item的格式;

          printf不能自行換行,如需換行需給定\n;

          使用修飾符可以使輸出格式更加美觀。

        (3)、format的格式指示符,以%開始,后跟一個字符

          %c:顯示字符的ASCII嗎

          %d,%i:十進制整數

          %e,%E:科學計數法顯示數值

          %f:顯示浮點數本身

          %g,%G:以科學計數法格式或浮點數顯示數值

          %s:顯示字符串

          %u:顯示無符號整數

          %%:顯示%自身

         修飾符

          #:字段的顯示寬度

          .#:取值精度

          -:左對齊

          =+:顯示數值的符號

        (4)、例:

          取出系統用戶的用戶名和默認shell,要求用戶名左對齊,占用15個字符,字符串顯示;要求默認shell左對齊,占用20字符,字符串顯示

          awk -F: ‘{printf "%-15s %-20s\n",$1,$7}' /etcpasswd 

         blob.png

         使用顯示浮點數自身(%f)的方式顯示,會自動補全精度,長于精度部分將會執行四舍五入

         # awk 'BEGIN{printf "%f\n",3.15}'

         blob.png

         當使用數字來定義字段占用字符長度時,要放在其它修飾符前面;小數點后面的數字代表精度

         # awk 'BEGIN{printf "%-15.2\n",3.15}'

         blob.png

    awk之action

        1、常見action

         (1)、表達式  Expression

         (2)、控制語句 Control statements

         (3)、組合語句 Commpound statments      

         (4)、輸入語句 Input statments

         (5)、輸出語句 Output statements

       2、awk常見控制語句以及使用示例

         (1)、if-else語句 格式:if (condition) {then body} else {else body}                

            # awk -F: '{if($3>=500{print $1 "is a common user"} else {print $1 "is admin or systemuser"}' /etc/passwd 

            uid號大于等于500的顯示為普通用戶,小于500的顯示為管理員或系統用戶。

            blob.png

           # awk -F: '{if(NF>=8){print}}' /etc/inittab 

            打印顯示以冒號切割形成字段大于等于8的行

            blob.png

         (2)、while語句 格式: 格式:while (condition) {while body}

            awk '{i=1;while(i<=NF){printf "%s ",$i;i+=2}; print ""}' /etc/inittab 

            打印輸出/etc/inittab中的奇數字段

            blob.png        

          打印出字符大于等于6的字段

          # awk '{i=1;while(i<=NF{if(length($i<=6){print $i};i++}}' /etc/inittab 

          blob.png                      

        (3)、do-while循環 格式:格式:do {do-while body} while (condition)

                             # awk 'BEGIN{sum=0;i=0;do{sum+=i;i+=}while{i<=100};print sum;}'

                            求和1-100

         blob.png

        (4)、for循環 格式:for (variable assignment; condition; iteration process) {for body}

                            # awk '{for(i=1,i<=NF,i+=2){printf "%s ",$1};print ""}' /etc/inittab

                          打印出/etc/inittab中的每行的奇數字段

                          blob.png

                          for循環還可以用來遍歷數組 格式:for (i in array) {for body}

                          # awk 'BEGIN{"date" | getline d; split(d,test);for (i in test) print test[i]}'

                          blob.png

                          break 用于在滿足條件的情況下跳出循環;continue用于在滿足條件時忽略后面的語句,直接返回循環的頂端

                     (5)、next提前結束本行處理,進入下一行處理

                          取uid為奇數的用戶和uid

                          # awk -F: '{if($3%2==0) next;print $1,$3}' /etc/passwd 

                          blob.png

                   (6)、數組

                          關聯數組

                      array[index-expression]index-expression:可以使用任意字符串;如果某數組元素事先不存在,那么在引用時,awk會自動創建次元素并將其初始化為空串;因此,要判斷某數組是否存在某元素,必須使用“index in array”這種格式A[first]="hello awk"print A[second]要遍歷數組中的每一個元素,需要使用如下特殊結構:for (var in array) {for body}期中var會遍歷array的索引,而非元素的值

                   (7)、awk的內置函數 split(string,array[,fieldsep[,seps]])能夠將string標示的字符串以fieldsep為分隔符進行切片,并切片后的結果保存至array為名的數組中;數組下表從1開始

         # awk 'BEGIN{split("root:x:0:0",user,":");for (i in user) print user[i]}'

        blob.png

      由于本人水平有限,awk的使用先總結到這里吧,在以后的使用中再深入研究。

    

                   



 


 

                    

  

       

    

原創文章,作者:Silently,如若轉載,請注明出處:http://www.www58058.com/6553

(0)
SilentlySilently
上一篇 2015-08-04
下一篇 2015-08-05

相關推薦

  • 數據庫基礎

    數據庫基礎 一、數據模型 數據庫模型圖 1、層次模型、2、網狀模型、 3、關系模型二維關系: 表:就是一個關系及屬性的描述,如:學生(學好,姓名,性別,班級)       行:row, entity       列:colume,…

    Linux干貨 2016-10-19
  • phpMyAdmin安裝部署

    phpMyAdmin安裝部署 phpMyAdmin 是一個用PHP編寫的軟件工具,可以通過web方式控制和操作MySQL數據庫。通過phpMyAdmin 可以完全對數據庫進行操作,例如建立、復制和刪除數據等等。如果使用合適的工具,MySQL數據庫的管理就會變得相當簡單。應用 MySQL 命令行方式需要對 MySQL 知識非常熟悉,對SQL語言也是同樣的道理?!?/p>

    2017-06-13
  • sed命令用法

    sed命令 [option]  “script”  file sed命令是一種行編輯工具,他是逐行對文件進行編輯。sed命令有一個模式空間,他將一行命令讀取進模式空間進行編輯,完成后將本行數據打印再讀取下一行數據進行處理。 option: -n:靜默模式不顯示模式空間內容 -f:從指定文件中讀取 -i:修改源文件(-i.###會自動將原文…

    Linux干貨 2016-08-12
  • 關于磁盤管理的例子

    今天來說一個關于磁盤管理的例子,通過這個例子也順便了解一下此例子涉及到的一些相關命令、文件。 練習:創建一個2G的文件系統,塊大小為2048byte, 預留1%可用空間,文件系統ext4,卷標為TEST,要求此分區開機后自動掛載至/test目錄,且默認有acl掛載選項 思路:1.在/etc/fstab中定義開機自動掛載信息    &nbs…

    Linux干貨 2017-08-19
  • 文件查找工具locate和find的使用分析

    文件查找工具locate和find的使用分析 不管是在windows系統中還是在Linux系統中,我們經常會一些文件進行搜索查找,而在Linux系統中經常用到的搜索工具有locate和find,這兩種搜索工具的工具原理和用法都不相同,一下將這對這兩種搜索工具的使用進行分析。 1、locate工具的工作原理是對/var/lib/mlocate/mlocat.d…

    Linux干貨 2016-08-18
  • mysql-proxy 讀寫分離

    1. 簡介     mysql-proxy 是官方為此的一個測試,項目, 可以完成讀寫分離。但是項目目前還不是很成熟,這里僅作測試。  2. mysql-proxy安裝部署 # wget http://downloads.mysql.com/archives/get/file/mysql-…

    Linux干貨 2015-12-21
欧美性久久久久