Linux 文本處理三劍客之“awk”

一、awk的工作原理和使用格式

基本語法:

       awk [option]... '/pattern/{action}' FILE

awk 的執行流程如下所述:

1、首先awk根據“行標記”讀取行(awk處理的單位是行)

   awk根據行標誌讀入一行(linux系統中默認的行結束標誌是:"\n")

2、然後,按要求做匹配

   awk會檢查讀取到行與指定的“pattern”做匹配,

   (1)、如果讀取到的行與指定的"pattern"不匹配,awk又讀取下一行。

   (2)、如果讀取到的行與指定的“pattern”匹配,awk就使用指定的段分隔符(默認爲空格,可以使

         用“-F”定義)對行進行切片,然後執行action。

awk的模式PATTERN有:

   (1)、使用地址範圍:

        start_line,end_line       從哪行開始到那行結束,指定處理範圍的行
        #                         指定處理那行
        /part1/,/part2/           匹配其中一個
        /parttern/                只匹配該模式的

     如:

    [root@www ~]# free | awk '/^Mem/{printf "%s:\t%0.1f%\n","FreeMen",($4+$6+$7)/$2*100}'
     FreeMen:        64.6%

   (2)、表達式:指的是比較表達式     

       >、>=、==、<、<=、!=、~(模式匹配)

      如:

       awk -F: '$3 >= 500{print $0}' /etc/passwd
       awk -F: '$7 ~ /bash$/{print $0}' /etc/passwd

    使用表達式做awk處理的行匹配時,還可以使用:&& 或 ||

      如:

       [root@www ~]# awk  -F: '$3 < 500 && $3 > 400 {print $0}'  /etc/passwd
       rtkit:x:499:497:RealtimeKit:/proc:/sbin/nologin
       saslauth:x:498:76:"Saslauthd user":/var/empty/saslauth:/sbin/nologin
       pulse:x:497:496:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
       mysql:x:496:493::/home/mysql:/bin/bash

3、最後輸出:action 

   (1)、有隻打印"print"不格式化。

   (2)、格式化“printf”之後輸出。

   說明:

        awk 是一種編程語言,awk對行進行切片之後,可以使用awk的算術運行與字符比較,判斷語

    句,對字段進行邏輯操作之後,再通過print與printf(print format)輸出。


二、【awk】是如何實現報告生成的呢?

使用printf 動作,進行數據的格式化操作.

printf的語法:

           printf "format(格式)", item1(字段),item2,...
要點:
   (1)、要指定format
   (2)、不會自動換行:如需換行則需要給出換行符:"\n"
   (3)、format用於爲後面的每個item指定其輸出格式
        是以字符串格式輸出還是以浮點數格式輸出或以十進制格式輸出呢

format格式的指示符都以“%”開頭,後跟一個字符

   
   %c:         顯示字符的ASCII碼
   %d, %i      十進制整數int
   %e, %E      科學計數法顯示數值
   %f          顯示浮點數float
   %g, %G      以科學計數法格式或浮點數格式顯示數值
   %s          顯示字符串string
   %u          顯示無符號整數
   %%          顯示%自身

format格式的修飾符:

    #          顯示寬度
    -          左對齊
    +          右對齊
    .#         取值精度

例:

    數據的格式化報告的生成方法:

1、第一步:使用printf動作支持的fromat格式,格式化數據。

    計算內存的剩餘百分比。

   [root@stu13 ~]# free | awk '/^Mem/{printf "%f\n",($4+$6+$7)/$2}'
   0.816848

2、第二步:使用format格式的修飾符,美化數據的輸出。

   [root@stu13 ~]# free | awk '/^Mem/{printf "%0.1f%\n",($4+$6+$7)/$2*100}'
   81.7%

說明:

    如果,我們對文本中的特定行的段,數據進行計算處理的話。使用【awk】是最好的。

先匹配(使用地址範圍)到需要處理的行,awk會根據指定的分隔符對匹配到的行進行切割。這時候我們就可以使用awk內置的算術運算對這些片段做數學運算了。且awk的格式化報告功能很強大。



例:

  格式化輸出:/etc/passwd文件中,用戶的ID號大於10且小於200的用戶和用戶ID號。

分析:

    由於【awk】命令的默認字段分隔符是:空格。所以要自定義字段分隔符。--------> awk切割字段的標準

    由於對用戶的ID號有要求,所以awk命令不是對每一行都進行切割,要做行匹配----->awk處理的行標準

    要使用到awk的action中的printf完成數據的格式化操作。

format的選擇:

        字段     選擇format

         $1      字符型格式輸出:s%
         $3      數值類型且十進制制格式輸出:d%

如下:

    [root@node1 ~]# awk -F: '$3<200 && $3>10{printf "%s%d\n",$1,$3}' /etc/passwd
    operator11
    games12
    gopher13
    ftp14
    nobody99
    dbus81
    usbmuxd113
    vcsa69
    rpc32
    avahi-autoipd170

說明:沒有指定字段分隔符,printf格式化的字符是連起來的。


使用linux系統中製表符"\t"做爲字段的分隔符。

    [root@node1 ~]# awk -F: '$3<200 && $3>10{printf "%s\t%d\n",$1,$3}' /etc/passwd
    operator        11
    games   12
    gopher  13
    ftp     14
    nobody  99
    dbus    81
    usbmuxd 113
    vcsa    69
    rpc     32
    avahi-autoipd   170
    haldaemon       68

說明:

    從上面顯示可以看出,字段與字符之間是分開了。 但是由於每個字段的長度不同所以。它們還不能對齊。

   所以,以最長的字段爲準,指定字段的顯示寬度。使用format的格式修飾符指定顯示寬度。

   [root@node1 ~]# awk -F: '$3<200 && $3>10{printf "%-13s\t%-13d\n",$1,$3}' /etc/passwd
   operator        11
   games           12
   gopher          13
   ftp             14
   nobody          99
   dbus            81
   usbmuxd         113
   vcsa            69
   rpc             32
   avahi-autoipd   170
   haldaemon       68
   ntp             38
a  pache           48

說明:以字段:avahi-autoipd 爲標準,它有13個字符。所以,格式化時指定每個字段佔用13. ------> 顯示寬度。“-”表示字段以左對齊的方式。


擴展:

    顯示/etc/passwd第4字段,第4字段是用戶的組ID號,所以選擇format格式的指示符爲:%d, 顯示寬度爲:13 且是左對齊。

    [root@node1 ~]# awk -F: '$3<200 && $3>10{printf "%-13s\t%-13d\t%-13d\n",$1,$3,$4}' /etc/passwd
    operator        11              0
    games           12              100
    gopher          13              30
    ftp             14              50
    nobody          99              99
    dbus            81              81
    usbmuxd         113             113
    vcsa            69              69
    rpc             32              32
    avahi-autoipd   170             170
    haldaemon       68              68

使用【BEGIN】模式增加標題:標明顯示的各個字段是什麼

    [root@node1 ~]# awk -F: 'BEGIN{printf "%-13s\t%-13s\t%-13s\n","UserName","User_PID","UserGroup_ID"}$3<200 && $3>10{printf "%-13s\t%-13d\t%-13d\n",$1,$3,$4}' /etc/passwd
    UserName        User_PID        UserGroup_ID
    operator        11              0
    games           12              100
    gopher          13              30
    ftp             14              50
    nobody          99              99
    dbus            81              81
    usbmuxd         113             113
    vcsa            69              69
    rpc             32              32
    avahi-autoipd   170             170

這樣:報告顯示清晰明瞭。

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