萬能的AWK

awk:文本三劍客之一

#報告生成器,主要用來實現格式化文本輸出,它能夠實現在處理文本文件時對文檔中的某字段有條件顯示并以非常美觀的文本;

它是編程語言的解釋器;它也是一種完整的編程語言,它支持條件判斷、循環、變量、數組、函數等等各種各樣的編程語言所能實現的功能。

用法:awk [options] ‘program’ FILE …

   program: PATTERN{ACTION STATEMENTS}

               PATTERN:awk在數據中查找的內容

       ACTION STATEMENTS:動作語句,對查找的內容執行的一系列命令,多為awk內置的命令print和printf;多個語句之間用分號分隔;     

          注意:program中的字符串要加雙引號。                                                    

      選項:

  -F:指明從文件中輸入數據時用到的字段分隔符;默認空白字符且不限制空白字符的個數,即同一行中一個空白字符、兩個空白字符、三個空白字符等都是分隔符;

  -v var=value: 自定義變量;

萬能的AWK

awk的print子命令

       用法:print item1, item2, …

       要點:

   輸出時默認以空白為分隔符;

   輸出的各item可以字符串,也可以是數值,還可以是當前記錄的字段(例如$1、$2等等)、變量或awk的表達式;其中數值在輸出時會被隱式轉換成字符串以字符格式輸出,但該數值參與運算時依然是數值;變量要想替換值一般不能用引號引起來;

   省略item相當于print $0(即打印整行);

萬能的AWK

備注:打印/etc/fstab文件中后5行的第2和4字段;

AWK的變量:有內建變量和自定義變量兩類;awk中引用變量不需要加$,只有引用字段變量時才用加$,例如$1、$2;

      ①內建變量

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

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

        RS:input record seperator,輸入行分隔符,默認為換行符;

        ORS:output record seperator,輸出行分隔符,默認為換行符;

        NF:number of field,每行字段數量

        {print NF}:打印行的字段數量

        {print $NF}:打印行的最后一個字段值

        NR:number of record, 行數或行號

        FNR:各文件分別計數;行數或行號

        FILENAME:文件名;

        ARGC:命令行參數的個數;

        ARGV:保存了命令行參數的數組;

  修改內建變量默認值:例如,#awk -v FS=”:”或#awk -F:(修改輸入分隔符為冒號)

萬能的AWK

可以看到效果。。。。。。

②自定義變量

       有兩種方法:

       1>-v var=value

         變量名區分字符大小寫;

       2>在program中直接定義

萬能的AWK

awk的printf子命令:格式化輸出

       用法:printf FORMAT, item1, item2, …

       要點:

           FORMAT必須給出;

           FORMAT中需要分別為后面的每個item指定一個格式符

           不會自動換行需要顯式給出換行控制符\n

               格式符:每一個格式符還可以有它的修飾符

                   %c: 顯示字符的ASCII碼;

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

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

                   %f:顯示為浮點數;

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

                   %s:顯示字符串;

                   %u:無符號整數;

                   %%: 顯示%自身;

               修飾符:用于格式符前面控制格式符顯示的機制

    #[.#]:第一個數字控制顯示的寬度;第二個#表示小數點后的精度,例如%3.1f

            -: 左對齊,默認右對齊;

            +:顯示數值的符號;

       注意:幾乎所有的編程語言都支持格式化輸出(包括bash);bash中也支持使用printprintf,不僅僅是echo

萬能的AWK

awk中的操作符

       ①算術操作符:

         x+y, x-y, x*y, x/y, x^y, x%y:加,減,乘,除,次方,取模

         -x:正數轉換為負數;

         +x: 字符串轉換為數值;

       ②字符串操作符:默認只有一個,即沒有符號的操作符(表示字符串連接);

       ③賦值操作符:=, +=, -=, *=, /=, %=, ^=(次方等),++, —

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

       ⑤模式匹配符:

 ~:是否匹配

 !~:是否不匹配

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

       ⑦函數調用:規范的函數調用方式,區別于bash中的函數調用;

         function_name(argu1, argu2, …):“argu1, argu2, …”為向函數傳遞的參數;

       ⑧條件表達式:selector?if-true-expression:if-false-expression

         selector是條件表達式,若selector為真則執行if-true-expression,否則執行if-false-expression;

PATTERN:實現地址定界的功能

       ①empty:空模式,即匹配每一行;

       ②/regular expression/:正則表達式,僅處理能夠被此處的正則表達式匹配到的行;“//”為模式符號,凡是正則表達式都要放在模式符號中;

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

       ④line ranges:行范圍;

         startline,endline:/pat1/,/pat2/

         注意:不支持直接給出數字的格式

       ⑤BEGIN/END模式

 BEGIN{}: 僅在開始處理文件中的文本之前執行一次,比如打印表頭;若不對文件做處理則運行在BEGIN模式中;

 END{}:僅在文本處理完成之后命令結束之前執行一次,比如打印處理結果;

萬能的AWK

萬能的AWK

萬能的AWK

蠻有意思的0.0

常用的action,有如下幾類;

       ①Expressions:表達式,例如“a=6”;

       ②Control statements:控制語句,例如if, while等;

       ③Compound statements:組合語句,即把多個語句組合起來當一個代碼塊,通常用花括號括起來;

       ④Input statements:輸入語句;

       ⑤Output statements:輸出語句;

 

  awk控制語句

       if(condition) {statments}(只有一個語句花括號可以省略,下同):

       if(condition) {statments} else {statements}

       while(conditon) {statments}

       do {statements} while(condition)

       for(expr1;expr2;expr3) {statements}

       break

       continue

       delete array[index]:刪除數組中的某個元素

       delete array:刪除整個數組

       exit

       {statements}

控制語句

  1)if-else:很少用到多分支語句

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

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

2)while循環

       語法:while(condition) statement,條件“真”,進入循環;條件“假”,退出循環;若首次條件判斷為假,則循環體執行0次。

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

 示例:
            awk ‘BEGIN{i=1;sum=0;while(i<=100){sum+=i;i++};print sum}’
            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)>=10) {print $i,length($i)}; i++}}’ /etc/grub2.cfg

3)do-while循環

       語法:do statement while(condition),與while的區別在于先執行一次循環體再判斷;

 

1+2+3+….100,計算累加的和?多種方法實現
        1.awk ‘BEGIN{ total=0;i=0;do{ total+=i;i++;}while(i<=100);print total}’
        2.awk ‘BEGIN{for(i=1;i<=100;i++){ sum+=i}print sum}’
        3.awk ‘BEGIN{i=1;sum=0;while(i<=100){sum+=i;i++};print sum}’
        4.seq -s “+” 100 |bc
        5.echo `seq 100|tr ‘\n’ ‘+’`0|bc
        6.echo {1..100}|tr ‘ ‘ “+” |bc
        7.for ((i=1,sum=0;i<=100;i++));do let sum+=i;done;echo $sum
        8.i=1;sum=0;while [ $i -le 100 ];do let sum+=i;let i++;done;echo $sum

  4)for循環:比while循環更簡潔更易懂

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

      詳解:for(variable assignment變量賦值;condition條件判斷;iteration process變量迭代) {for-body循環體}

 

      特殊用法:能夠遍歷數組中的元素;

  語法:for(var in array_name) {for-body}

 示例:

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

5)switch語句:多分支if語句,類似bash中case語句,但是關鍵字不同;常用于字符串等值比較或模式匹配判斷;

      語法:switch(expression) {case VALUE1 or /REGEXP/: statement; case VALUE2 or /REGEXP2/: statement; …; default: statement}:expression和“VALUE1 or /REGEXP/”

       

  6)break和continue

       break [n]:跳出n層循環,控制行內循環(即字段間循環);

       continue:跳出當前循環直接進入下一輪循環,控制行內循環;

 

  7)next:控制awk的內生循環(即行間循環)提前結束對本行的處理而直接進入下一行;

      備注:使用while、do-while、for編寫的循環控制awk的行內循環;

     

8)array:較多使用關聯數組;

       關聯數組:array[index-expression]

           index-expression:

        ①可使用任意字符串,字符串要加雙引號;

        ②如果某數組元素事先不存在,在引用時awk會自動創建此元素并將其值初始化為“空串”,當把該“空串”當數值使用時其值為零;

       數組元素賦值詳見“2016.01.05-bash編程之數組和字符串處理(1)”

       數組元素引用使用print而非$;

       判斷數組中是否存在某元素要使用“index in array”格式進行判斷;

       遍歷數組中的每個元素要使用for循環,格式為“for(var in array) {for-body}”,var會遍歷array的每個索引;

 示例:
        weekdays[“mon”]=”Monday”;awk ‘BEGIN{weekdays[“mon”]=”Monday”;weekdays[“tue”]=”Tuesday”;print weekdays[“mon”]}’
        awk ‘!arr[$0]++’ dupfile         #去重,所有行都第一次打印
        awk ‘{!arr[$0]++;print $0, arr[$0]}’ dupfile          #跟蹤執行過程
        awk -F: ‘{arr[$1]=$3;print arr[$1]}’ /etc/passwd
        awk -F: ‘{arr[$1]=$0;print arr[NR]}’ /etc/passwd
        awk -v n=0 ‘!n{print}’ /etc/passwd
    若要遍歷數組中的每個元素,要使用for循環
        for(var in array) {for-body}
    注意: var會遍歷array的每個索引
示例:
        awk ‘BEGIN{sum=0;for(i=1;i<=100;i++){if(i%2==0)continue;sum+=i}print sum}’
        awk ‘BEGIN{sum=0;for(i=1;i<=100;i++){if(i==66)break;sum+=i}print sum}’
        awk -F: ‘{if($3%2!=0) next; print $1,$3}’ /etc/passwd                              #打印奇數行
        awk -F: ‘{if($3%2!=1) next; print $1,$3}’ /etc/passwd                             #打印偶數行
        awk -F: ‘{if($3%2!=0) {next;} else {print $1,$3}}’ /etc/passwd

函數

  1)內置函數

       數值處理:

           rand():返回0和1之間一個隨機數,此處的隨機指首次隨機;

       字符串處理:

   length([s]):返回指定字符串的長度;

           sub(r,s,[,t]):以r表示的模式來查找t所表示的字符中的匹配的內容,并將其第一次出現替換為s所表示的內容;該功能sed和grep更易用;

   gsub(r,s,[,t]):以r表示的模式來查找t所表示的字符中的匹配的內容,并將其所有出現均替換為s所表示的內容;該功能sed和grep更易用;

           split(s,a[,r]):以r為分隔符切割字符s并將切割后的結果保存至a所表示的數組中;awk中的數組下標從1開始;

  2)自定義函數:極少用;

數值處理:
        rand():返回0和1之間一個隨機數
        awk ‘BEGIN{srand(); for (i=1;i<=10;i++)print int(rand()*100) }’
            srand() 是生成種子,rand才可以生成隨機數,二者需要配合使用
            int() 可以對浮點數取整
    字符串處理:
        length([s]):返回指定字符串的長度
        sub(r,s,[t]):對t字符串進行搜索r表示的模式匹配的內容,并將第一個匹配的內容替換為s
            echo “2008:08:08 08:08:08” | awk ‘sub(/:/,“-“,$1)’
        gsub(r,s,[t]):對t字符串進行搜索r表示的模式匹配的內容,并全部替換為s所表示的內容
            echo “2008:08:08 08:08:08″ | awk ‘gsub(/:/,”-“,$0)’
            echo “2008:08:08 08:08:08” | awk ‘gsub(“:”,”-“,$0)’
        split(s,array,[r]):以r為分隔符,切割字符串s,并將切割后的結果保存至array所表示的數組中,第一個索引值為1,第二個索引值為2,…
            netstat -tan | awk ‘/^tcp\>/{split($5,ip,”:”);count[ip[1]]++}END{for (i in count) {print i,count[i]}}’

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

(0)
All wellAll well
上一篇 2017-04-22 21:17
下一篇 2017-04-22 22:01

相關推薦

  • 通配符、正則表達式小計

    基本通配符:    *: 匹配任意長度的任意字符;    ?: 匹配任意的單個字符;    []: 匹配指定范圍內的任意單個字符;    [^]: 匹配非指定范圍內的任意單個字符;   簡單示例:   &nbs…

    Linux干貨 2017-03-16
  • Net25-第10周作業

    1、請詳細描述CentOS系統的啟動流程(詳細到每個過程系統做了哪些事情) Centos系統啟動過程分內核空間啟動和用戶空間啟動: 內核空間啟動流程: POST: post加點自檢,檢測計算機基本5大件是否完好,計算機可被正常點亮。 BootSequence: 位于ROM上的BIOS的BootSequence來選擇啟動順序 Bootloader: 決定啟動順…

    Linux干貨 2017-03-15
  • 文本處理-vim編輯器

    命令格式、(1)模式、(2)關閉文件、(3)可視化模式、(4)使用多個“窗口”、(5)定制vim的工作特性、(6)示例

    2018-03-13
  • Linux啟動之GRUB詳解

    GRUB 在BIOS讀取先關信息之后,接下來就是去第一個可以啟動的設備當中的MBR中讀取Boot loader信息,bootloader具有菜單功能、直接加載內核信息,以及相關控制權限轉交功能。所以說系統的啟動必須有bootloader,然后才能去加載內核 grub:GRand Unified Bootloader  …

    Linux干貨 2016-09-15
  • Linux磁盤管理命令

    Linux有著管理各種存儲設備的強大能力。Linux把所有磁盤都當作文件管理,從而簡化我們對其進行的讀寫等操作。 IDE接口的硬盤在Linux中命名為:/dev/hd{a|b|c……},比如/dev/hda; 其他硬盤比如SATA接口的硬盤命名為:/dev/sd{a|b|c……},比如/dev/sda。 注:{…

    Linux干貨 2015-12-06
  • N22-第5周博客作業

    1、顯示當前系統上root、fedora或user1用戶的默認shell; grep -E "^(root|fedora|user1)\>" /etc/passwd | cut -d: -f7 2、找出/etc/rc.d/init.d/functions文件中某單…

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