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 12:53
下一篇 2015-08-05 09:49

相關推薦

  • Python函數式編程指南(二):函數

    這是此系列的第二篇,試圖說明在Python中如何更好地使用函數并引導諸位使用函數式的思維進行思考。掌握并應用這些內容,就已經是至少形似的函數式風格的代碼了,至于思維么,這個真靠自己。 作者水平有限,如有錯漏之處還請指出;轉載請注明原作者和原地址:) 2. 從函數開始 2.1. 定義一個函數 如下定義了一個求和函數: def add(x, y): return…

    Linux干貨 2015-03-11
  • day5總結筆記

    本文內容: 索引節點 硬鏈接與軟鏈接 重定向 用戶組 useradd命令 索引節點: 索引節點包含了一個表,包含了有關文件的元數據,包含:     文件類型,權限,UID,GID 鏈接數(指向這個文件名路徑名稱個數)      該文件的大小和不同的時間戳。&n…

    系統運維 2016-08-08
  • old notes

    yum update: update software guest edition ***: how to install guest edition: 1) need to root: su – 2) yum install kernel-devel 3)yum install gcc* ( when don't remember n…

    Linux干貨 2016-09-19
  • grep簡述

    grep(Globel Search Regular Expression and Printing out the line) 它能使用正則表達式搜索文本,并把匹配的行打印出來。 grep包括grep、egrep和fgrep。 egrep表示擴展的grep,相比grep支持更多的匹配模式, “grep -E”相當于egrep。 fgrep是fast gre…

    2017-04-06
  • 對修改提示符引起的一些問題的理解

    有一個練習:提示符修改過后永久保存,每次打開一個新的shell,提示符都為已設定好的格式,不會因為打開新的shell而不同。 在做這個練習的時候遇到了不少問題,通過不斷bing,將起初很陌生的問題一點點的解決,得到了一些理解,因此將理解寫下來。 提示符與變量PS1有關,PS1的值可以被修改或重新賦予。PS1的值變,則提示符也會變。通過搜索得到只要在/etc/…

    Linux干貨 2017-07-15
  • 關于綁定與不綁定CPU的對比

        此文嚴格意義上說,我沒有很大的把握,其中關于CPU調度域的概念現在還有些混淆,但還是發出來,希望能做點鋪路的貢獻吧。    另外CPU調度域的原理我沒辦法自己寫,能力尚淺, 只能將IBM知識庫 和 另一位博主的文章摘錄如下,并添加了些幫助理解的圖片,希望能幫助到初學者。 …

    Linux干貨 2016-05-03
欧美性久久久久