AWK

GNU awk

全稱:Aho,Weiberger,Kernighan,是三個作者的名字,所以簡稱為awk

awk:報告生成器,主要用來格式化文本輸出的,它能夠實現在處理文本文件時對文檔中的字段有條件的顯示,而且將顯示的結果用非常美觀的文本形式給予輸出。我們所用的awk其實就是gawk,他是一個符號鏈接指向gawk的。

gawk – pattern scanning and processing language:模式掃描及處理語言

  awk其實就是一個解釋器,是一個編程語言的解釋器,從本質上來講他也是一個編程語言,支持條件判斷、數組、循環等各種各樣一個編程語言當中幾乎所有的功能。因此我們又可以把gawk稱為一個腳本語言解釋器,他所支持的是一個單獨的腳本編程語言的功能。和bash編程語言一樣,也是過程式編程語言。另外gawk也有自己內置的變量,允許用戶自定義變量。

awk的基本用法:

awk [options] 'program' FILE ...
    paogram的組成:PATTERN{ACTION STAEMRNTS(動作語句)}:可以有多個語句,語句之間用分號分割。

    選項:
        -F:指明輸入時用到的字段分隔符:從文件中讀取數據時以什么當作分割符
        -v var=varlaue:用于實現自定義變量:

awk常用的輸出命令:

1、print

print item1,item2,...
    要點:
        (1)逗號分隔符:
        (2)輸出的各item可以是字符串,也可以是數值,也可以是當前記錄的字段,變量或awk的表達式
        (3)如省略item,相當于print $0(打印整行)

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:num of record:行數
        FNR:各文件分別計數:行數
        FILENAME:當前文件名
        ARGC:命令行參數的個數
        ARGV:是一個數組,保存的是命令行所給定的各參數
自定義變量   
        (1)-v var=value
            變量名區分字符大小寫:
        (2)在program中直接定義

3、printf

格式化輸出:printf FORMAT,item1,item2,...
        (1)FORMAT必須給出
        (2)不會自動換行,需要顯示給出換行控制符,\n
        (3)FORMAT中需要分別為后面的每個intem指定一個格式化符號
            格式符:
                %c:顯示字符的ASCII碼
                %d,%i:顯示十進制整數
                %e,$E:科學計數法數值顯示
                %f:顯示為浮點數
                %g,%G:以科學計數法或浮點形式顯示數值
                %s:顯示字符串
                %u:無符號整數
                %%:顯示%號自身 
            修飾符:
                #[.#]:第一個數字控制顯示的寬度:第二個#顯示小數點后的精度:
                -:左對齊
                +:顯示數值的符號

4、操作符

算術操作符:
        x+y,x-y,x*y,x/y,x^y,x%y
        -x
        +x:轉換為數值:
    字符串操作符:沒有符號的操作符,字符串連接的意思
賦值操作符:
        =,+=,-=,*=,/=,%=,^=
        ++,--
比較操作符:
        >,>=,<,<=,!=,==
模式匹配符:
        ~:是否匹配
        !~:是否不匹配
邏輯操作符:
        &&,||,!
函數調用:
        function_name(argu1,argu2,...)
條件表達式:
        selector?if-true-expression:if-fales-expressiion
        示例:格式化顯示/etc/passwd文件中用戶名是普通用戶還是系統用戶還是管理員
        awk -F: '{$3>=500?usertype="Common User":usertype="Sysadmin or Sysuser";printf "%15s:%-s\n",$1,usertype}' /etc/passwd

5、pattern

(1)empty:空模式,匹配每一行
(2)/regular expression/:僅處理能夠被此處模式匹配到的行
(3)relational expression:關系表達式:結果有“真”有“假”,結果為“真”才會被處理;
    真:結果為非0值為真,非空字符串也為真
(4)line ranges:行范圍,指明起始行,指明結束行
    startline,endline:/pat1/,/pat2/
    注意:不支持直接給出數字的格式,須使用如下格式
    示例:顯示/etc/passwd中第2行到第10行的用戶名
    ~]# awk -F: '(NR>=2&&NR<=10){print $1}' /etc/passwd
(5)BENGIN/END模式
    BENGIN{}:僅在開始處理文件中的文本之前執行一次:
    END{}:僅在文本處理完成之后執行一次

6、常用的action

(1)Expressions:表達式
(2)Control statements:控制語句,if,while,for等
(3)Compound statemens:組合語句
(4)input statemens:輸入語句
(5)output statemens:輸出語句

7、控制語句

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

控制語句說明
    (1)if-else
    語法:if(condition) statement [else statement]
    ~]# awk -F: '{if($3>=500) {printf "Common user: %s\n",$1} else {printf "root or Sysuser: %s\n",$1}}' /etc/passwd
    ~]# awk -F: '{if($NF=="/bin/bash") print $1}' /etc/passwd
    示例:顯示/etc/fstab文件中字段數大于5的行
    ~]# awk '{if(NF>5) print $0}' /etc/fstab
    示例:顯示當前使用空間大于20的設備名稱
    ~]# df -h | awk -F[%] '/^\/dev/{print $1}' |awk '{if($NF>=20) print $1}'
    使用場景:對awk取得的整行或某個字段做條件判斷
    (2)while循環
    語法:while(condition) statemnt
        條件為真進入循環:條件為假退出循環
    使用場景:對一行內的多個字段逐一類似處理時使用:對數組中的各元素逐一處理時使用:

    ~]# 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
    (3)do-while循環
    語法:do statement while(condition)
        意義:至少執行一次循環體
    (4)for循環
    語法:for(expr1;expr2;expr3) statement
        for(variable assignment;conditiion;iteration process) {for-body}
        ~]# awk '/^[[:space:]]*llinux16/{for(i=1;i<=NF;i++) {print $i,length($i)}}' /etc/grub2.cfg
        特殊用法:
            能夠遍歷數組中的元素:
            語法:for(var in array) {for-body}
    (5)switch語句
    語法:switch(expression) {case VALUE1 or /REGEXP/: statement;case VALUE2 or /REGEXP2/: statement;...;default: statement}
    (6)break和continue
        break [n]
        continue
    (7)next
        提前結束對本行的處理而直接進入下一行
    示例:顯示ID號為偶數的用戶
    ~]# awk -F: '{if($3%2!=0) next; print $1,$3}' /etc/passwd

8、array

關聯數組:array[index-expression]
    index-expreesion
        (1)可使用任意字符串;字符串要使用雙引號
        (2)如果某數組元素事先不存在,在引用時,awk會自動創建此元素,并將其值初始化為“空串”
            如要判斷數組中是否存在某元素,要使用“index in array”格式進行
            weekdays["mon"]="Monday"
            如要遍歷數組中的每個元素,要使用for循環
                for(var in  array) {for-boby}
                ~]# awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="tuesday";for(i in weekdays) {print weekdays[i]}}'
            注意:var會遍歷array的每個索引
                示例:顯示各端口的狀態次數
                ~]# netstat -tan | awk '/^tcp\>/{state[$NF]++}END{for(i in state) { print i,state[i]}}'
                示例:顯示每個ip地址訪問httpd服務的次數
                ~]# awk '{ip[$1]++}END{for(i in ip) {print i,ip[i]}}' /var/log/httpd/access_log
            練習1:統計/etc/fstab文件中每個文件系統類型出現的次數
                ~]# awk '/^UUID/{fs[$3]++}END{for(i in fs) {print i,fs[i]}}' /etc/fstab
            練習2:統計指定文件中每個單詞出現的次數;
                ~]# awk '{for(i=1;i<=NF;i++){count[$i]++}}END{for(i in count) {print i,count[i]}}' /etc/fstab

9、函數

(1)內置函數
    數值處理
        rand():返回0和1之間一個隨機數
    字符串處理
        length([s]):返回指定字符串的長度
        sub(r,s,[t]):以r表示的模式來查找t所表示的字符串中的匹配的內容,并將其第一次出現替換為s所表示的內容
        gsub(r,s,[t]):以r表示的模式來查找t所表示的字符串中的匹配的內容,并將其所有出現均替換為s所表示的內容
        split(s,a,[r]):以r為分割符切割字符s,并將切割后的結果保存至a所表示的數組中
        ~]# netstat -tan | awk '/^tcp\>/{split($5,ip,":");count[ip[1]]++}END{for (i in count) {print i,count[i]}}'
(2)自定義函數
練習:

顯示/etc/fstab文件后五行的第2和第4個字段

]# tail -5 /etc/fstab  |awk '{print $2,$4}'

顯示/etc/fstab文件后五行的第2和第4個字段,并且在輸出的行首顯示“ali”字符,在行尾顯示數字“1”。

]# tail -5 /etc/fstab |awk '{print "ali",$2,$4,1}'

顯示/etc/passwd文件中的第1個字段,要求awk內建變量輸入分割符為冒號

]# awk -v FS=':' '{print $1}' /etc/passwd

使用冒號為分割符顯示/etc/passwd文件中的用戶名

]# awk -F: '{print $1}' /etc/passwd

使用輸入分隔符為冒號和輸出分隔符為冒號顯示/etc/passwd文件的第1,3,7字段(以冒號為分割符顯示/etc/passwd中用戶名,UID,shell類型)

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

以空格為屬入換行符顯示/etc/passwd文件

]# awk -v RS=' ' '{print }' /etc/passwd

顯示/etc/fstab文件中每行的字段數

]# awk '{print NF}' /etc/fstab

顯示/etc/passwd文件中每行的最后一個字段

]# cat /etc/passwd |awk -F':' '{print $NF}'

分別顯示/etc/fstab和/etc/issue文件的行數

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

格式化顯示/etc/passwd文件中每行的用戶名,UID,shell類型,要求對應顯示username,uid,shelltype

]# awk -F: '{printf "username: %s, uid: %d, shelltype: %s \n",$1,$3,$7}' /etc/passwd

格式化顯示/etc/passwd文件中每行的用戶名,UID,shell類型,要求對應顯示username,uid,shelltype,并且格式輸出寬度為15個字符,左對齊。

]# awk -F: '{printf "username: %-15s, uid: %-15d, shelltype: %-15s \n",$1,$3,$7}' /etc/passwd

顯示/etc/fstab文件中以UUID開頭的行

]# awk '/^UUID/{print }' /etc/fstab

顯示/etc/fstab文件中不以UUID開頭的行

]# awk '!/^UUID/{print }' /etc/fstab

顯示UID大于500的用戶名和UID

]# awk -F: '$3>=500{print $1,$3}' /etc/passwd
]# awk -F: '{if($3>=500)print $1,$3}' /etc/passwd

顯示shell類型為bash的用戶

]# awk -F: '$NF=="/bin/bash"{print $1,$NF}' /etc/passwd
]# awk -F: '$NF~/bash$/{print $1,$NF}' /etc/passwd

原創文章,作者:M20-1馬星,如若轉載,請注明出處:http://www.www58058.com/48725

(0)
M20-1馬星M20-1馬星
上一篇 2016-09-23
下一篇 2016-09-23

相關推薦

  • 2

    2

    Linux干貨 2018-03-26
  • 第11天:網絡基礎,屬性配置

    http://note.youdao.com/noteshare?id=bf6e776e7271953bffe1bdf949df4e8f

    Linux干貨 2016-09-06
  • DNS簡單配置

    正向解析,反向解析,主從, 主:主配置文件:options {        listen-on port 53 { 127.0.0.1; 172.16.252.194; };  //監聽的端口,即哪些主機可以進行訪問        directory   &…

    Linux干貨 2017-05-24
  • linux下文件處理基礎命令(自己預習瞎學的)

                      Linux下文件處理基礎命令     1.創建文件   有時候我們會遇到需要創建一個空文件的情況。比如,應用程序可能希望在寫…

    2017-07-15
  • 深入解析:分布式系統的事務處理經典問題及模型(轉載分享)

    摘要:分布式系統需要在數據完整、一致性和性能間做平衡。本文系統介紹了處理分布式數據一致性的技術模型,如:Master-Slave,Master-Master,2PC/3PC,經典的將軍問題,Paxos,以及Dynamo的NRW和VectorClock的模型。 編者按:數據服務的高可用是所有企業都想擁有的,但是要想讓數據有高可用性,就需要冗余數據寫多份。寫多份…

    Linux干貨 2015-04-04
  • 軟件包管理(rpm篇)

    軟件包管理(rpm篇)靜態和動態鏈接    鏈接主要作用是把各個模塊之間相互引用的部分處理好,使得各個模塊之間能夠正確地銜接,分為靜態鏈接和動態鏈接    靜態鏈接        把程序對應的依賴庫復制一份到包&nbsp…

    Linux干貨 2017-04-24
欧美性久久久久