awk工具的使用

awk是一個功能強大的文本分析工具,在centos中,awk與gawk是同一個命令 

~]# ls -l /usr/bin/awk
lrwxrwxrwx. 1 root root 4 10月 14 2017 /usr/bin/awk -> gawk

可以看到,awk文件是gawk文件的一個符號鏈接


格式:

    gawk [options] 'program' file ...        

        program:[/PATTERN/]{ACTION statement;...}

            PATTERN部分:決定動作語句何時觸發以及通過什麼事件觸發

 

    常用選項:

-f,--file program-file:從指定的文件中加載program語句塊,而不是通過命令行給出相關的程序內容;

-F,--field-separator fs:指定字段的輸入分隔符;默認是空白字符;

-v,--assign var=val:用於聲明自定義變量併爲變量賦值;

                

基本概念:    

    1.分隔符:

        輸入分隔符:

    awk對數據進行處理時,會根據特定的標識符號對數據進行分段處理,這種標識符號就稱爲"輸入分隔符",默認的輸入分隔符是空白字符;如果指定的分隔符並沒有被數據包括,則只有換行分隔符有效;


        輸出分隔符:

            awk對數據處理完成後,會以特定的標識符號對各個字段進行連接後輸出,這種標識符號就稱爲"輸出分隔符",默認的輸出分隔符是空白字符;


    2.記錄:由換行符進行分隔的數據中一行,就稱爲一條記錄(Record);通常在使用awk處理數據時,使用內置變量$0來保存整個記錄的內容;


    3.字段:經過分隔符分隔之後的每一個數據分段,都成爲一個字段(Field);通常在使用awk處理數據時,使用$1,$2...$NF等內置變量來存儲各個字段的數據;



awk的工作原理:

    1.首先,執行BEGIN{ACTION statement;...}語句塊中的語句;

    2.其次,從文件中或着標準輸入讀取一行,根據PATTERN的匹配結果執行後面的ACTION語句塊中的內容;然後逐行重複該過程已完成數據處理,直到數據全部被讀取完畢;

    3.最後,在所有的語句塊都執行完成之後,退出awk進程之前,執行END{ACTION statement;...}語句塊中的語句;


    注意:

1) BEGIN語句塊在awk開始處理數據內容之前就被執行;通常用於生成表頭;此語句塊是可選語句塊;

2) END語句塊在處理完所有的數據之後,纔會被執行;通常用於數據彙總;此語句塊是可選語句塊;

3) PATTERN語句塊中的通用命令是最重要的部分,因此PATTERN語句塊不能省略,但其中的ACTION可以省略,如果省略,則默認執行print動作,即:顯示數據的各行;

4) awk在執行PATTERN語句塊時,默認循環遍歷數據中的各個記錄;


awk常用用法:

    1.變量:

        1)內建變量:           

            FS:輸入字段分隔符,默認爲空白字符;

    OFS:輸出字段分隔符,默認爲空白字符;

                示例:指定輸入字段分隔符爲":",輸出字段分隔符爲":",輸出/etc/passwd文件中每行的第1、3、7個字段

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

                    blob.png


                    其中,使用"-F:"選項效果與"-v FS=':'"相同

                    blob.png

            

            RS:輸入記錄(行)分隔符,默認爲換行符;

注意:即使指定了額外的輸入記錄分隔符,原有的換行符依然有效;

    ORS:輸出記錄分隔符,默認爲換行符;

                示例:指定輸入記錄分隔符爲":",輸出記錄分隔符爲"#",輸出每個記錄的內容:

awk -v RS=':' -v ORS='#' '{print $0}' /etc/passwd

                     blob.png


            

            NF:每一行中的字段的總數;

示例:顯示指定文件中每行中的字段的數量

awk -F: '{print NF}' /etc/passwd

                    blob.png

                注意:如果語句爲print $NF,則會輸出每行中最後一個字段

                    blob.png

                可以使用print $(NF-1)語句輸出每行中倒數第二個字段:

                    blob.png


            NR:行的總數;如果僅處理一個文件,可以將NR的值當作此文件中各行的行號;當處理多個文件時,該命令將兩個文件的行號累加輸出

                示例:輸出/etc/fstab文件各行行號

awk '{print NR}' /etc/fstab

                    blob.png

    

            

            FNR:對於不同的文件分別統計其行的數量;即使處理多個文件,也可以顯示每個文件中每行的行號;

示例:分別輸出/etc/fstab和/etc/issue文件的各行行號

awk '{print FNR}' /etc/fstab /etc/issue

                    blob.png


            

            FILENAME:當前正在被處理的文件的文件名;

示例:處理/etc/fstab後在最後輸出正在處理的文件名:

awk 'END{print FILENAME}' /etc/fstab

                    blob.png

                    注:如果在PATTERN部分不添加END,則會輸出與文件行數相同行的文件名


            

            ARGC:命令行中參數的數量;包括awk命令本身,但不包括awk命令的選項部分和program部分;

示例:

awk 'END{print ARGC}' /etc/fstab /etc/issue /etc/passwd

                    blob.png


            

            ARGV:由命令行中所有的參數構成的數組;

示例:

awk 'END{print ARGV[1]}' /etc/fstab /etc/issue /etc/passwd

    blob.png

        
        2)自定義變量

            定義方式:-v var_name=value,注意變量名大小寫敏感

            示例:以"USERNAME,hello"格式輸出/etc/passwd下記錄的所有用戶名

awk -v var='hello' -F: '{print $1"," var}' /etc/passwd

                    blob.png

    

    2.print動作:以標準格式輸出結果

        格式:

            print item1,item2,...

            注意:                

                1) 各item之間需要使用","進行分隔;

2) 輸出的各item可以是字符串,可以是數字,可以是當前記錄中的字段,可以是變量,可以是awk的表達式;

3) 如果省略了item,則默認的item爲$0,即:輸出整行;


        示例:輸出/etc/issue文檔中每行的第1、3和最後一個字段:

awk '{print $1,$3,$NF}' /etc/issue

                blob.png

            輸出字符串:

awk 'BEGIN{print "hello world"}'

                blob.png


    3.printf動作:以特定的格式輸出結果

        格式:           

            printf "FORMAT" item1,item2,...

    注意:

1) 必須給出合適的輸出格式;

2) 默認不會自動換行,如果想要在輸出結果中換行顯示,需要顯式給出換行控制符號,即:\n;

3) FORMAT中需要爲後面的每一個item單獨指定一個格式化符號;


        常用的FORMAT:            

            %c:以ASCII碼錶中的內容顯示字符信息;

    %d, %i:顯示十進制整數;

    %e, %E:以科學計數法來顯示數字;浮點類型;

    %f, %F:顯示十進制數字的浮點形式;

    %g, %G:以科學計數法顯示浮點數字;

    %u:顯示無符號十進制數;

    %s:顯示字符串;

    %x, %X:顯示無符號的十六進制整數;

    %%:顯示%;

        修飾符:         

            #[.#]:第一個數字用來控制顯示寬度;第二個數字表示小數點的精度;

如:%5s, $8.3f

    -:表示採用左對齊方式顯示;默認是右對齊;

    +:顯示數字的正負符號;


            示例:以左對齊,寬度20,輸出字符串型的用戶名,並且以左對齊,寬度,輸出整型的UID

awk -F: '{printf "%-20s %-5d\n",$1,$3}' /etc/passwd


    4.操作符:       

        1)算術運算操作符:

    雙目運算符:

x+y, x-y, x*y, x/y, x^y, x%y

    單目運算符:

-x:將正整數轉換爲負整數;

+x:將字符串轉換爲數值;


示例:

awk 'BEGIN{print 100^2}'


        2)字符串操作符:

    無任何操作符號時,即爲字符串連接操作;


3)賦值操作符:

    =, +=, -=, *=, /=, ^=, %=,++, --


4)比較操作符:可以放在PATTERN部分作爲匹配條件

    ==, !=, >, >=, <, <=

示例:輸出UID爲1000的行的記錄

awk -F : '$3==1000{print $0}' /etc/passwd

              blob.png  

        5)模式匹配操作符:

    ~:操作符左側的字符串是否能夠被右側的PATTERN所匹配;

    !~:操作符左側的字符串是否不能被右側的PATTERN所匹配;

示例:輸出所有bash爲/bin/bash的用戶的記錄

awk -F : '$NF~/\/bin\/bash/{print $0}' /etc/passwd

           blob.png 


        6)邏輯運算操作符:

            &&,||,!

        示例:輸出所有UID在1000到9000以內的用戶記錄

awk -F: '$3>=1000&&$3<=9000{print $0}' /etc/passwd

            blob.png


        7)條件表達式:    

            selector(condition)?if-true-expression:if-false-expression

            示例:以"USERNAME:USERTYPE"格式顯示/etc/passwd中記錄的所有用戶,其中UID大於等於1000的USERTYPE爲"Common User",UID小於1000的USERTYPE爲"SuperUser or Sysuser"

awk -F: '{$3>=1000?usertype="Common User":usertype="SuperUser or Sysuser";print $1","usertype}' /etc/passwd

                blob.png


    5.PATTERN部分:        

        1) empty:空模式,不加區分地處理文件的每一行;

2) [!]/REGEXP/:僅處理[不]能被PATTERN匹配到的行;

3) 關係表達式:

4) 行域,行範圍:

    ①關係表達式的邏輯運算:FNR>=10&&FNR<==20

                示例:

awk -F: '/^r/,/^a/{print FNR,$0}' /etc/passwd

            blob.png

awk 'NR>=1&&NR<=3{print NR,$0}' /etc/passwd

                    blob.png

    ②/REGEXP1/,/REGEXP2/: 從被REGEXP1匹配的行開始,直到被REGEXP2匹配的行結束,這期間的所有行,有多少組就顯示多少組;

            示例:

                awk -F: '/^r/,/^a/{print NR,$0}' /etc/passwd

                blob.png

    5) BEGIN/END模式:

        BEGIN{}:僅在開始處理文件中的第一行文本數據之前執行一次的語句塊;多用於輸出特定格式的表頭信息;

        END{}:僅在文本處理完成但awk命令尚未退出時執行一次的語句塊;多用於數據信息的彙總;

    示例:

awk -F: 'BEGIN{printf "%20s %10s %20s\n","USERNAME","USERID","SHELL"}NR>=15&&NR<=20{printf "%20s %10s %20s\n",$1,$3,$7}END{print "------------------------------------------------------------------\n",NR " users"}' /etc/passwd

                blob.png

    注意:

                1) BEGIN語句塊,PATTERN語句塊和END語句塊的順序,通常來講是:

    BEGIN{}PATTERN{}END{}

                2) BEGIN語句塊和END語句塊是可選的,但PATTERN語句塊必須要給出;


    6.控制語句:       

        1) if ... else:

        語法:

    if (condition) statement [ else statement ]

    使用場景:對awk取得的整行或某個字段做條件判斷;


        示例:

    awk -F: '{if($3>=1000){print "CommonUser:",$1}else{print "Sysuser:",$1}}' /etc/passwd

                blob.png


        輸出使用率大於80%的設備名:

            df -h | awk -F% '/^\/dev/{print $1}' | awk '{if($NF>=80){print $1}}'

        2) while循環:

        語法:

            while (condition) statement

        使用場景:

            a.對一行內的多個字段逐一做相同或類似的操作處理時使用;

            b.對數組中的各數組元素做遍歷處理時使用;


        while循環的特點:條件爲真,進入循環;一旦條件爲假,則退出循環;


        示例:輸出/etc/passwd各行各個字段,並統計字符數

awk -F: '{i=1;while(i<=NF){print $i,length($i);i++}}' /etc/passwd

            blob.png

        3) do ... while語句:

        語法:

            do statement while (condition)


        意義:與while循環相同,但statement語句段至少被執行一次;


        4) for循環:

        語法:

            for (expr1; expr2; expr3) statement

                expr1:variable assignment,變量賦初值;

                expr2:circle condition,循環條件判斷;

                expr3:interation process,變量值修正方法;


        示例: 輸出/etc/passwd各行各個字段,並統計字符數        

awk -F: '{for(i=1;i<=NF;i++){print $i,length($i)}}' /etc/passwd

            blob.png


        5) switch ... case語句

        語法:

        switch (expression) { case value|regex:statement;case value2|regex2:statement;... [ default: statement ] }

        示例:   

 awk -F: '{switch($2){case "x":printf "nopassword "}print $1}' /etc/passwd

            blob.png

        使用場景:

            用於進行字符串比較判斷;


        6) break和continue語句:

            break [n]

            continue


        示例:

        awk -F: '{for(i=1;i<=NF;i++){if(length($i)<5){continue}else{print $i,length($i)}}}' /etc/passwd

            blob.png


        7) next語句:

            在awk處理數據時,提前結束對當前行的處理,而直接開始處理下一行;


        示例:

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

                blob.png


    

    8.數組——Array

        用戶自定義的數組,一般使用關聯數組:array_name[index_expression]

    注意:

1) index_expression可以使用任意的字符串,但字符串必須放在雙引號中;

2) 支持弱變量數組,即:如果某數組元素事先不存在,當引用該元素時,awk會自動創建此元素,併爲此元素賦"空字符串"作爲其初始值;


    示例:

awk 'BEGIN{name["leader"]="zhangsan";name["mem1"]="lisi";name["mem2"]="bob";for(i in name){print name[i]}}'

                blob.png


    查看當前系統上所有服務的不同TCP狀態的連接數量的統計:

netstat -nalt | awk '/^tcp\>/{state[$NF]++}END{for(stat in state){printf "%15s: %-10d\n",stat,state[stat]}}'

blob.png

            用於統計本服務器web站點的每個用戶的請求數值:

awk '{ipaddr[$1]++}END{for(ip in ipaddr){print ip,ipaddr[ip]}}' /var/log/httpd/access_log


    用於統計本服務器web站點的UV值:

awk '{ipaddr[$1]++}END{for(ip in ipaddr){print ip,ipaddr[ip]}}' /var/log/httpd/access_log | wc -l


    9.函數:

內建函數:

    數值函數:Numeric Functions

rand():返回一個介於0到1之間的隨機數;

sqrt():對於指定的數值進行開二次方;


    字符串函數:String Functions

        length():計算給定字符串的長度;

gsub(r, s [, t]):以r表示的模式來查找t表示的字符串中能夠被匹配的內容,並將所有出現的內容替換成s表示的內容;

split(s, a [, r [, seps] ]):以seps作爲分隔符,利用r表示的模式進行匹配,將s代表的字符串分割之後,保存在a表示的數組中;


    自定義函數:

function name(parameter list) { statements }


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章