1. 程式人生 > >gawk 文本處理入門用法詳集

gawk 文本處理入門用法詳集

awk 函數 數組

awk筆記

gawk - pattern scanning and processing language

報告生成器,可進行格式化輸出,文本處理三劍客之一,是基於sed和grep功能的擴展

一般用法格式:

awk [options] ‘program‘ FILE...
    program: /regular/{print}

語句之間用分號分隔
print,printf

選項:

-F:指明輸入時用到的字段
-v var=value:指明自定變量

awk運作方式:

逐行讀入文本,並將每個字段給予一個變量進行存儲,$1..$NF ,而$0標識一整行
顯示文本的的2,4字段,默認是空格為分隔符,默認輸出以空格為分隔符

tail -3 /etc/fstab  | awk ‘{print $2,$4}‘

1.print item1,item2...

        以逗號作為分隔符
        變量的引用,不允許在""內部
        省略item,則默認print $0

2.變量

1.內鍵變量

FS:input field seperator指明輸入字段分隔符類似-F
OFS:output field seprator 指明輸出字段分隔符
RS:input record seperator輸入時的換行符

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

ORS:output record seperator輸出時的換行符
NF:number of field,每行的字段數量
$NF:最後一個字段
NR:number of record,行數
FNR:各文件分別計數
FILENAME:當前的文件名
ARGC:命令行參數的個數(program 不為參數)

                ]# awk ‘BEGIN{print ARGC}‘ /etc/fstab

ARGV:數組,保存,命令行中所給定的每個字段

2.自定義變量

-v var=value
變量名區分大小寫

                ]# awk -v test=‘hello gawk‘ ‘BEGIN{print test}

在program中直接定義

                ]# awk ‘BEGIN{test="hello gawk";print test}‘

3.printf命令:格式化輸出

        printf "FORMAT1,FORMAT2",item1,item2... ===>FORMAT與item對應位置的格式化
            1.FORMAT是必須要給出
            2.printf不自動換行,顯式給出換行符\n
            2.FORMAT需要分別為後面的每個item指定一個格式化符號
格式符(需用雙引號):
                    %c :顯示字符的ASCII碼
                    %d %i:顯示十進制整數
                    %e %E:科學計數法數值顯示
                    %f:顯示浮點數
                    %g,%G:以科學計數法或浮點數顯示數值
                    %s:顯示字符串
                    %u:無符號整數
                    %%:顯示%自身

格式化輸出示例:

            ]# awk -F: ‘{printf "Username: %s\n",$1}‘ /etc/passwd
修飾符:加在格式符之前,用於控制格式符的顯示方式

#.# 第一個數字控制顯示寬度;第二個#表示小數點後的精度

                       %3.2f
                    - : 顯示為左對齊
                    + : 顯示數值的符號,有正數負數之分

示例:

            ]# awk -v FS=‘:‘ ‘{printf "username: %-25s,UDI: %-25d\n",$1,$3}‘ /etc/passwd

4.操作符

算術操作符

            x+y,x-y,x*y,x^y,x/y,x%y
            -x:正數轉化為負數
            +x:字符串轉化為數值

字符串操作符:沒有符號的操作符,字符串的連接

        賦值操作符:
            =,+=,-=,*=,/=,%=,^=
            ++,--
        比較操作符:
            >,<,>=,<=,!=,==
        模式匹配符:
            ~:是否匹配
            !~:是否不匹配
        邏輯操作符:
            &&
            ||
            !

函數調用:

            function_name(argu1,argu2,...)
        條件表達式:(三目運算)
            selctor?if-true-expression:if-false-expression

示例:查找本機的普通用戶及系統用戶

                # awk -F: -v OFS=":"  ‘{$3>1000?usertype="common user":usertype="system user";printf "%-18s,%s\n",$1,usertype}‘ /etc/passwd

5.PATTERN

1 .empty:空模式,匹配每一行

2 ./regular expression/:文本過濾僅處理被模式匹配到的行

            ]# awk ‘/^UUID/{print $1}‘ /etc/fstab

3 .relatinal expression:關系表達式:結果為真式,才會被處理;非零為真

            ]# awk -F:  ‘$3>=1000{print $1,$3}‘ /etc/passwd

查找其用戶的默認shell為/bin/bash的用戶

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

4 .lines ranges:行範圍
startline,endline
註意:不支持直接指定數字,可以容如下方式

            ]# awk -F: ‘(NR>=2&&NR<=5){print $1,$2}‘ /etc/passwd
        /part1/,/part2/
            ]# awk -F: ‘/^h/,/^9/{print $1}‘ /etc/passwd

5 .BEGIN/END模式:處理開始之前處理一次
BEGIN{}:僅在開始處理文件中的文件之前執行一次:
END{}:僅在文本處理完成之後執行一次

        ]# awk -F: ‘BEGIN{print "username uid \n----------"}{print $1,$3‘ /etc/passwd

6 .常用的action:

        1.expressions
        2.control statements:if ,while,等;
        3.compound statements:組合語句;
        4.input statements
        5.output statements

7 .控制語句

        if(condition) {statements} else {statments}
        while(condition) {statements}
        for(expr1;expr2;expr3) {statements}
        {statements}組合語句需要{}
  1. if-else

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

         ]# awk -F: ‘{if($3>=1000) {printf "common user:%s\n",$1} else {printf "system user: %s\n ",$1}}‘ /etc/passwd

    取得磁盤利用率:

         ]# df -h| awk -F [%] ‘/^\/dev/{print $1}‘|awk ‘{if($NF>=10) print $1}‘
  2. while循環:

    語法:while(condition) statements

    條件為"真",進入循環;條件為假則退出循環
    使用場景:對一行內的多個字段逐一處理,對數組中的字段做逐一處理

    函數:length()字符長度

    統計每個字段的長度?

           ~]# awk ‘/[[:space:]]*linux16/{i=1;while(i<=NF) {print $i,length($i);i++}}‘ /etc/grub2.cfg

    並統計出大於7的字段?

           ~]# 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)
               意義:先執行循環語句,而後在判斷執行while循環
  4. for循環:

    語法:for(expr1;expr2;expr3) statement
    for(variable assignment;condition;iteration proccess) {for-body}

           ~]# awk ‘/[[:space:]]*linux16/{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 /REGEXP/:statement...;default statement}
  6. break和continue

           break [n] :跳出n層循環
  7. next

           提前結束對本行的處理而直接進入下一行
               僅顯示偶數的uid用戶?
           ~]# awk -F: ‘{if($3%2!=0) next; print $1,$3}‘ /etc/passwd
  8. array
    關聯數組:array[index-expression]

     index-expression:
         1.可使用任意字符串;索引要使用雙引號"";array["mon"]=Monday
         2.如果某元素事先不存在,在引用時awk會自動將此元素創建並將其賦值為空串

若要判斷數組中是否存在某元素,要使用"index in array"格式進行
若要遍歷數組中的每個元素,要使用for循環:

for(var in array) {for-body}

    ~]# awk ‘BEGIN{weekdays["mon"]="monday";weekdays["tue"]="tuesday";for(i in weekdays) {print weekdays[i]}}‘
        註意:var會遍歷array的每個索引;

查看netstat -nat中tcp狀態出現的次數?

        ~]# netstat -tan |awk ‘/^tcp\>/{state[$NF]++}END{for(i in state) {print i,state[i]}}‘

查看ss -nat中tcp狀態出現的次數?

        ~]# ss -tan |awk ‘{state[$1]++}END{for(i in state) {print i,state[i]}}‘

查看ip地址的訪問量?

        ~]# awk ‘{ip[$1]++}END{for(i in ip) {print i,ip[i]}}‘ /var/log/httpd/access_log

統計/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():返回指定字符串的長度;
        字符處理:
            length([s]):返回指定字符串的長度;
            sub(r,s,[t]):以r表示模式查找t所表示的字符中匹配的內容,並將其第一次出現替換為s所表示的內容;
            gsub(r,s,[t]):以r表示模式查找t所表示的字符中匹配的內容,並將全局出現替換為s所表示的內容;
            splits(s,a[,r]):以r為分隔符切割字符s,並將切割後的結果保存至a所代表的的數組中

統計ip地址出現的次數?

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

本文出自 “老城小敘” 博客,請務必保留此出處http://cityx.blog.51cto.com/9857477/1927819

gawk 文本處理入門用法詳集