AWK

awk:報告生成器,格式化文本輸出

        處理方式:文件里有多行,awk處理時,先將第一行放到內存里面,然后將該行分割成列(字段),第一個字段叫$1,第二個字段$2,以此類推,$0代表整行。

        基本用法:

                awk [option] 'program' var=value file…..

                awk [option] -f programfile var=value file……

                awk [option] 'BEGIN{action;….} parttern{action;…..}END{action;……}' file

                                語句之間要用“”;”分號分割

                awk 程序通常由:BEGIN語句塊、能夠使用模式匹配的通用語句塊、END語句塊,共3部分組成

         option:

                    -F :指明輸入時用到的字符分隔符(不指明系統默認空白或tab為分隔符)

                    -v: var=value 自定義變量

        

             1、print item1,item2….

                            不同item之間要用“”,“”逗號作為分隔符,且輸出顯示時用空格隔開

                            如果此處省略item,則相當于print $0,文件有多少行,則打印多少個行

                            輸出的item可以是字符串,也可以是數值,當前記錄的字段,變量或awk的表達式

            

             2、變量

                            內置變量:

                                    FS:input field seperator 輸入字段分隔符,默認為空白符

        awk -v FS=":" '{print $1,$3}' /etc/passwd  等同于 awk -F: '{print $1,$3}' /etc/passwd

                                    OFS:output field seperator 輸出字段分隔符,默認空白符

        awk -F: -v OFS="----" '{print $1,$3}' /etc/passwd        
        xixi----3015
        aa----3016
        apache----48

                                    RS:input record seperator 輸入時的換行符

                                    ORS:output record seperator 輸出時的換行符

                                    NF:number of field,字段數量

                                                print NF:打印字段數量   print $NF:打印最后一個字段

        awk -F: '{print NF}' /etc/passwd        
        7
        ...
        7
        awk -F: '{print $NF}' /etc/passwd
        /bin/bash
        ....
        /sbin/nologin

                                    NR:number of record 行號

            root@centos7.2  ~ # awk -F: '{print NR,$0}' /etc/fstab /etc/issue            
            1 
            .......
            11 UUID=fca23b64-0367-45b2-ab0e-b391bbba6ec8 swap   swap    defaults   0 0
            12 \S
            ..........
            17 \n
            18 \t

                                    FNR:每個文件進行單獨記錄行號

            root@centos7.2  ~ # awk -F: '{print FNR,$0}' /etc/fstab /etc/issue            
            1 
            ......
            10 UUID=068d63ab-d4b7-4e1f-b00b-c182785fa85d /boot   xfs   defaults   0 0
            11 UUID=fca23b64-0367-45b2-ab0e-b391bbba6ec8 swap   swap    defaults        0 0
            1 \S
            ......
            6 \n
            7 \t

                                    FILENAME:顯示文件名

            root@centos7.2  ~ # awk '{print FILENAME,$0}' /etc/issue            
            /etc/issue \S
            ........
            /etc/issue \n
            /etc/issue \t

                                    ARGC:命令行參數的個數

            root@centos7.2  ~ # awk '{print ARGC}' /etc/issue            
            2
            2
            2

                                    ARGV:數組,保存命令行中的各個參數,ARGV[0]

            root@centos7.2  ~ # awk '{print ARGV[0]}' /etc/issue            
            awk
            。。。。
            awk

                            自定義變量:

                                 a、-v var=value  注意變量名區分大小寫

            root@centos7.2  ~ # awk -v a="superman" 'BEGIN{print a}{print a,$0}' /etc/issue            
            superman
            superman \S
            superman Kernel \r on an \m
            ........
            superman \t

                                b、在program直接定義

            root@centos7.2  ~ # awk 'BEGIN{a="superman";print a}'             
            superman

        

             3、printf命令:

                            格式化輸出:printf format,item1,item2…….

                                 注意:format必須要給出

                                            不會自動換行,需要給出換行符"\n"

                                            format 中需要分別為后面的每個item指定一個格式化符號;

                                    格式符:

                                            %c:顯示字符的ASCII碼

                                            %d:顯示十進制整數

                                            %f:顯示為浮點數

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

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

                                            %s:顯示字符串

                                            %u:無符號整數

                                            %%:顯示% 自身

                                    修飾符:

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

                                                       %3.1:右對齊          %-3.1:左對齊            %+3.1:顯示數值的符號

            root@centos7.2  ~ # awk -F: '{printf "UserName:%-16s,Uid:%10d\n",$1,$3}' /etc/passwd
            UserName:root            ,Uid:         0
            UserName:bin             ,Uid:         1
            UserName:daemon          ,Uid:         2
            UserName:adm             ,Uid:         3

             4、操作符

                            算數操作符:  x+y,x-y,x*y,x/y,x^y,-x,+x:轉換為數值

            root@centos7.2  ~ # awk 'BEGIN{print 4*5}'            
            20

                            字符串操作符:沒有符號的操作符

                            賦值操作符: =,+=,-=,*=,/=,%=,^= ,++,–

            awk 'BEGIN{i+=5;print i}'

                            比較操作符:>,>=,<,<=,!=,==

                            模式匹配符:

                                                ~:是否匹配
                                                !~:左側的字符串是否不能夠被右側的字符串匹配

            root@centos7.2  ~ # awk -F: '$0~/root/' /etc/passwd            
            root:x:0:0:root:/root:/bin/bash
            operator:x:11:0:operator:/root:/sbin/nologin
            root@centos7.2  ~ # awk -F: '$0~/^root/' /etc/passwd
            root:x:0:0:root:/root:/bin/bash
            root@centos7.2  ~ # awk -F: '$0~"root"' /etc/passwd
            root:x:0:0:root:/root:/bin/bash
            operator:x:11:0:operator:/root:/sbin/nologin
            root@centos7.2  ~ #
            root@centos7.2  ~ # awk -F: '$1=="root"' /etc/passwd
                        root:x:0:0:root:/root:/bin/bash

                            邏輯操作符:&&,||,!

            root@centos7.2  ~ # awk -F: '$3>=0 && $3<=1000 {print $1}' /etc/passwd
            root
            bin
            .......
            root@centos7.2  ~ # awk -F: '$3 ==0 || $3>=1000 {print $1}' /etc/passwd
            root
            nfsnobody
            .....
            root@centos7.2  ~ # awk -F: '!($3>=500) {print $3}' /etc/passwd
            0
            1
            2

                            函數調用:function_name(argu1,argu2,。。。)

                            條件表達式:

                                            selector?if-true-experssion:if-false-expression  注意第二個if前面是“”:“”冒號

            如果UID大于1000就顯示為普通用戶,否則顯示為系統用戶,并打印出用戶名和uid            
            awk -F: '{$3>=1000?user="common user":user="system user";print user":"$1":"$3}' /etc/passwd

                     

             5、Pattern

                            1)empty:處理文本的每一行

                            2)/regular expression/:僅能夠處理被此模式匹配到的行

            root@centos7.2  ~ # awk '/^UUID/{print $1}' /etc/fstab             
            UUID=5f2cc971-2611-46f5-a14c-9e730cd33aa0
            UUID=068d63ab-d4b7-4e1f-b00b-c182785fa85d
            UUID=fca23b64-0367-45b2-ab0e-b391bbba6ec8

                            3)relational expression:關系表達式:結果有真有假,如果為真才會處理,真表示結果為非0值,非空位真

            awk -F: '$3>=1000{print $3}' /etc/passwd
            awk -F: '$NF=="/bin/bash"{print $1,$NF}' /etc/passwd
            awk -F: '{if($NF=="/bin/bash")print $1}' /etc/passwd     ###if判斷要放到{}里面
            awk -F: '$NF~/bash$/{print $1,$NF}' /etc/passwd

                            4)relational expression: 關系表達式;結果有“真”有“假”;結果為“真”才會被處理;
                                            真:結果為非0值,非空字符串
                                            假:結果為空字符串

            awk 'j=1{print $0};i=0{print i,j}' /etc/passwd   ###j=1的print動作會執行
            awk ‘!arr[$0]++’file 去除文件中的重復行
            root@centos7.2  ~ # seq 10 | awk 'i=!i'  ###打印基數行  awk ?。╥=!i) 打印偶數行
            1
            3
            5
            7
            9

                            4)地址定界:行范圍

                                        startline,endline:/part1/,/part2/

         awk -F: '/^root/,/^naruto/{print $1,$NF}' /etc/passwd  注意不支持直接給出數字的格式
         awk -F: '(NR>=2&&NR<=10){print $1}' /etc/passwd 打印2-10行   ### 不帶if的在{}外面判斷
         上述表達式等同于awk -F: '{if(NR>=2&&NR<=10)print $1}' /etc/passwd

                            5)BEGIN/END模式

                                        BEGIN{}:僅在開始處理文件之前執行一次的程序

                                        END{}:僅在文件處理之后執行一次

awk -F: 'BEGIN{print " username  uid \n--"}{printf "%-10s  %s\n",$1,$3}END{print "---\nend"}' /etc/passwd

    

             6、常用的action

                            1)experssions 表達式
                            2)Control statements,if,while等
                            3) compund statements:組合語句;
                            4)input statements
                            5)output statement 輸出語句

             7、控制語句

                            if(condition){statements}
                            if (condition){statements} else {statements}
                            while (condition){statments}
                            do {statements} while(condition)
                            for (expr1;expr2;expr3){statements}
                            break
                            continue
                            delete array [index]
                            delete array
                            exit

                    7.1 if-else

                            語法:if (condition)statement [else statement]

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

            awk -F: '{if(NR>=2&&NR<=10)print $1}' /etc/passwd   ###if判斷在{}里面
            awk -F: '{if($3>=1000) {printf "ComUser:%s\n",$1} else {printf "rootUser: %s\n",$1}}' /etc/passw
            
            awk -F: '{if($NF=="/bin/bash")print $1}' /etc/passwd
            awk -F: '{if(NF>5)print $0}' /etc/passwd 

            df | awk -F"%" '/^\/dev/{print $1}' | tr -d %|awk '{if($NF>=20)print $1}'

                                    注意:如有else 其兩邊都要加{}

                    7.2 while循環

                            語法:while(condition) statement,條件真進入循環,條件假退出

                            使用場景:對一行內的多個字段逐一類似處理時使用,對數組中的各個元素逐一處理時使用

            awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {print $i,length($i);i++}}' /etc/grub2.cfg
            awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {if(length($i)>=7)print $i,length($i);i++}}' /etc/grub2.cfg

                    7.3 do-while循環

                            語法:do statement while(condition)
                            意義:至少執行一次循環體

                    7.4 for循環

                            語法:for(expr1;expr2;expr3)statement

            awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) {print $i,length($i)}}' /etc/grub2.cfg

        

                    7.5 switch語法
                            語法:switch(expression) {case Value1 or /regexp/:statement;case\ value2 or /regexp2/:statement;….default:statement}

                    7.6 break和continue 用法同bash
                            break [n]

            root@centos7.2  ~ # awk 'BEGIN{sum=0;for(i=1;i<=100;i++){if(i==11){break}sum+=i}print sum}'            
            55

                            continue

            root@centos7.2  ~ # awk 'BEGIN{sum=0;for(i=1;i<=100;i++){if(i%2==0){continue}sum+=i}print sum}'            
            2500

                    7.7 next  能提前結束本行的處理,進入下一行

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

                    7.8 性能比較  time(command)

            root@centos7.2  ~ # time (awk 'BEGIN{sum=0;for(i=1;i<=100000;i++){sum+=i};print sum}')            
            5000050000
            real    0m0.046s
            user    0m0.032s
            sys    0m0.014s

            root@centos7.2  ~ # time (sum=0;for((i=1;i<=100000;i++));do let sum=$[sum+i];done;echo $sum)
            5000050000
            real    0m1.085s
            user    0m1.042s
            sys    0m0.044s

    

            root@centos7.2  ~ # awk 'BEGIN{sum=0;for(i=1;i<=10000;i++){sum+=i}}{print }END{print sum}'            
            ##沒有任何輸出結果,等待輸入,因為沒有文本傳入,且END是等待處理問文本之后才輸出,所以在此處處于等待狀態
            
            root@centos7.2  ~ # awk 'BEGIN{sum=0;for(i=1;i<=10000;i++){sum+=i}}{print }END{print sum}' /etc/passwd
            root:x:0:0:root:/root:/bin/bash
            .......
            apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
            50005000

             8、array數組

                        關聯數組:array[index-expression]
                                1)可以使用任意字符串;字符串要加雙引號
                                2)如果某數組元素事先不存在,在引用時,awk自動創建此元素,并將其值初始化為“空串”

            root@centos7.2  ~ # awk 'BEGIN{weekdays["mon"]="monday";weekdays["tue"]="tuesday";print weekdays["tue"]}'
            tuesday

                        要遍歷數組中的每個元素,要使用for循環,注意:var會遍歷array的每個索引

                                    for(var in array )

            root@centos7.2  ~ # awk 'BEGIN{weekdays["mon"]="monday";weekdays["tue"]="tuesday";for(i in weekdays)print weekdays[i]}'            
            tuesday
            monday
            root@centos7.2  ~ # netstat -tan | awk '/^tcp\>/{state[$NF]++}END{for(i in state){print i,state[i]}}'
            LISTEN 4
            ESTABLISHED
            root@centos7.2  ~ # awk '{ip[$1]++}END{for(i in ip){print i,ip[i]}}' /var/log/httpd/access_log            
            192.168.1.101 56
            192.168.1.103 14
            ::1 10
            統計/etc/fstab文件中每個文件系統類型出現的次數
            awk '/^UUID/{fs[$3]++}END{for(i in fs){print i,fs[i]}}' /etc/fstab
            統計指定文件中每個單詞出現的次數
            awk '{for(i=1;i<=NF;i++){count[$i]++}}END{for(i in count){print i,count[i]}}' /etc/fstab

             9、函數

                        內置函數
                                數值處理:
                                        rand():返回0和1 之間一個隨機數,小數

            awk 'BEGIN{print rand()}' ### 第一次取隨機的,之后再取,同上次一樣
             awk 'BEGIN{srand();print rand()}'   ###如需每次取值都不一樣需要調用srand()函數

                        字符串處理:
                                        length([s]):返回指定字符串的長度
                                        sub(r,s,[t]):以r表示的模式查找t所表示的字符串中的匹配的內容,并將其第一次出現替換為s所表示的內容
     

            root@centos7.2  ~ # echo "2008:08:08 08:08:08" | awk 'sub(/:/,"",$1)'
                        200808:08 08:08:08

            awk -F: '{print sub(o,O,$1)}' /etc/passwd

                                        gsub:表示全局替換
                                        split(s,a[,r]):以r為分隔符切割字符,并將切割后的結果保存在a所表示的數組中;

            netstat -tan | awk '/^tcp\>/{split($5,ip,":");count[ip[1]++]}END{for(i in count) {print i,count[i]}}'

                            

                        自定義函數

                                   格式:

                                        function name(parameter,parameter,……){

                                                 statements

                                                 return expression

                                        }

                                    示例:

            #cat fun.awk            
            function max(v1,v2) {
            v1>v2?var=v1:var=v2
            return var
            }
            END{a=3;b=2;print max(a,b)
            root@centos7.2  ~ # awk -f fun.awk
            3
            #!/bin/awk -f
             # 內容要寫awk的語法,-f指定要讀取文件內容
            function max(v1,v2) {
                 v1>v2?var=v1:var=v2
                 return var
            }
            BEGIN{a=3;b=2;print max(a,b);}
            root@centos7.2  ~ # ./fun.awk
            3
                        #!/bin/awk -f
                         # 內容要寫awk的語法,-f指定要讀取文件內容
                        function max(v1,v2) {
                             v1>v2?var=v1:var=v2
                             return var
                        }
                        BEGIN{print max(a,b);}
                        root@centos7.2  ~ # ./fun.awk -v a=100 -v b=200
                        200

               

                        awk中調用shell命令:

                                    system命令:

                                             空格是awk中的字符串連接符,如果system中需要使用awk中的變量可以使用空格分隔,或者說除了awk的變量外其他一律用""引用起來。

            awk 'BEGIN{system("hostname") }'            
            awk 'BEGIN{a=12; system("echo " a) }'

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

(0)
NarutoNaruto
上一篇 2016-09-26
下一篇 2016-09-26

相關推薦

  • 如何在微軟云上搭建mysql主從

    大家好: 今天我分享下在生產環境的微軟云服務器上如何搭建mysql主從: 環境如下圖: 我把cnux06-testing設為Mysql主服務器,暫時沒需求的cnux04-web1db2設為Mysql從服務器 1–首先要在master上開啟binlog日志功能并使主從庫中的 server-id保持不同 操作步驟如下: A: 先查看mysql的主目錄…

    Linux干貨 2017-02-14
  • 磁盤管理

    1、設備文件 設備文件:關聯至一個設備驅動程序,進而能夠跟與之對應硬件設備進行通信 設備號碼: 主設備號major number,標識設備類型 次設備號minor number,標識同一類型下的不同設備 [root@localhost ~]# ll /dev/sd* brw-rw—-. 1 root disk 8,  0 Aug 25 …

    Linux干貨 2016-09-01
  • 有趣的bash腳本

    1、編寫腳本/root/bin/createuser.sh,實現如下功能:使 用一個用戶名做為參數,如果指定參數的用戶存在,就顯示 其存在,否則添加之;顯示添加的用戶的id號等信息 #!/bin/bash read -p “Please input username: ” n if id $n &> /dev/null;then echo “T…

    Linux干貨 2017-08-25
  • 22期第十三周課堂練習

    1、建立samba共享,共享目錄為/data,要求:(描述完整的過程)   1)共享名為shared,工作組為magedu;   2)添加組develop,添加用戶gentoo,centos和ubuntu,其中gentoo和centos以develop為附加組,ubuntu不屬于develop組;密碼均為用戶名;   3)添加s…

    Linux干貨 2017-01-09
  • yum與rpm包

    yum與rpm包 包命名和工具 包:分類和拆包 Application-VERSION-ARCH.rpm:主包 Application-devel-VERSION-ARCH.rpm 開發子包 Application-utils-VERSION-ARHC.rpm 其它子包 Application-libs-VERSION-ARHC.rpm 其它子包 包之間:可…

    Linux干貨 2017-05-08
  • MySQL高級特性-合并表

    1. Merge Tables         如果愿意的話,可以把合并表看成一種較老的、有更多限制的分區表,但是它們也有自己的用處,并且能提供一些分區表不能提供的功能。 合并表實際是容納真正的表的容器??梢允褂锰厥獾腢NION語法來CREATE TABLE。下面是一個合并表的例子: mysql> &n…

    Linux干貨 2015-04-13

評論列表(1條)

  • 馬哥教育
    馬哥教育 2016-09-26 11:12

    awk是一個很方便的文本格式化工具,這也是以后面試題必會遇到的面試題,希望下來多加練習,熟練掌握.

欧美性久久久久