linux中awk工具的使用(轉)


add by zhj: awk很強大,它是一個簡單的編程語言,國外有本專門的書介紹它的用法。《effective awk programming》,它支持整型,字符串型,數組,變量在使用前不需要

定義,直接使用,因為每種數據類型都有默認的初始值。它還支持if/for等邏輯語句

原文:https://blog.51cto.com/13866901/2166164?tdsourcetag=s_pctim_aiomsg

運行環境:centos6 Vmware

一、awk簡介

awk是一個非常好用的數據處理工具,相對於sed常常作用於一整個行的處理,awk則比較傾向於一行當中分成數個【字段】處理,因此,awk相當適合處理小型的數據數據處理。awk是一種報表生成器,就是對文件進行格式化處理的,這里的格式化不是文件系統的格式化,而是對文件內容進行各種“排版”,進而格式化顯示;在linux中我們使用的是GNU awk簡稱gawk,並且gawk其實就是awk的鏈接文件,因此在系統上使用awk和gawk是一樣的。


二、awk的基本用法

awk[OPTIONS]'program' FILE1 FILE2

program:PATTERN{ACTION STATEMENT}

program:編程語言 PATTERN:模式 ACTIONSTATEMENT:動作語句,可以是多個語句,但多個語句中間要使用分號分隔

OPTIONS:-F[] 指明輸入字段分割符 ; -v VALUE 變量賦值;

舉例說明:

cat /etc/passwd
 

image.png

cat ceshi.txt |awk -v FS: '{print $1,$3}'(每行按冒號分割,輸出第一個域和第三個域;默認為空格分割;注意:awk后續動作都要以單引號引起來)
 

image.png

cat ceshi.txt |awk -v FS: '{print $1"XXXX"$3}'("XXXX"代表任意內容,必須用雙引號引起來)
 

image.png


三、變量

1、內建變量

  • FS 輸入字段分隔符,默認為空白

  • RS 輸入的記錄分隔符,默認為換行符

  • OFS 輸出字段分割符,默認為空白字符

  • OFS 輸出字段分隔符,默的認為換行符

  • NF 當前行的字段的數量

  • print NF 顯示當前行的字段數

  • print $NF 顯示當前行的第NF字段的值       

 

 

  • NR 記錄號

  • FNR 個文件分別計數,顯示行號

  • FILENAME 當前文件名

  • ARGC 命令行參數的個數

  • ARGV 保存命令行所給定的各參數的數組

2、自定義變量

(1)-v VALUE (變量名稱區分大小寫)在這里文件ceshi.txt中有多少行就顯示多少行變量的值

awk -v fan="cool" '{print fan}' ceshi.txt
 

image.png

(2)在program中自定義變量

awk 'BEGIN{FS=":";abc=1}{print $abc}' ceshi.txt
 

image.png


四、awk的格式化輸出

語法 printf FORNAT,item1,item2

  • FORMAT必須提供

  • 與print語句不同,printf不會自動換行,需要使用換行符\n

  • FORMAT中需要分別為后面的每個item指定一個格式符,否則item無法顯示;

格式符介紹:

  • %c 顯示字符的ASCII碼

  • %d ,%i 顯示為十進制整數

  • %e,%E 科學技術法顯示數值

  • %f 顯示為浮點數

  • %g,%G 以科學技術法或浮點數格式顯示數值

  • %s 顯示為字符串

  • %u 顯示無符號整數

  • %% 當需要顯示%號時需要連續打兩個百分號

舉例說明:

cat ceshi.txt |awk -F: '{printf "%-10s%s\n",$1,$3}'
 

image.png


五、awk的操作符

  • 算術操作符     如:A+B A-B A*B A/B

  • 字符操作符     字符串鏈接

  • 賦值操作符     如:== += /= %=

  • 比較操作符     如:> >= < <=

  • 模式匹配操作符  ~ 是否能由右側指定的模式所匹配  !~是否不能由右側指定的模式所匹配

  • 邏輯操作符     && 與運算 || 或運算

  • 條件表達式     selector?if-true-expression:if-ials-expreion  

  • 函數調用        調用函數來進行數據的處理

舉例說明

通過df命令查看當前系統磁盤占用率,查出占用率大於等於百分之20的磁盤名稱以及磁盤占用率

df|awk -v FS=% '$0 ~ "/dev/sd" {print $1}'|awk '$NF>=20 {printf "DevName:%-10s Used:%s%%\n",$1,$5}'
 

image.png

awk -v FS=: '{$3>=5?usertype="Big User":usertype="Small User";printf "UserName:%-15s Type:%s\n",$1,usertype}' ceshi.txt
 

image.png


六、awk的控制語句

  • if(condition){statements}[else {statement}]

awk -F: '{if($3>=5){printf "%-10s%s\n",$1,$3}}' ceshi.txt
 

image.png

  • while循環 while(condition){statements}

echo {1..10} |awk '{n=1;while(n<=NF){if($n%2==0){print $n,"oushuo"}else {print $n,"jishu"};n++}}'
 

image.png

  • do-while循環

  • for循環

awk BEGIN'{for(i=1;i<=1000;i++){sum+=i};print sum}'
 

image.png

  • break

  • continue

  • delete array

  • exit

  • next     提前結束對本行文本的處理,而提前進入下一行的處理操作

awk -F: '{if($3%2==0)next;print $1,$3}' ceshi.txt
 

image.png


七、awk的性能測試

實驗:從1加到100等於多少?

(1)time seq -s "+" 5000000 |bc

image.png

(2)time awk BEGIN'{for(i=1;i<=1000000;i++){sum+=i};print sum}'

image.png

(3)time awk BEGIN'{i=1;while(i<=1000000){sum+=i;i++};print sum}'

image.png

(4)time for ((i=1;i<=1000000;i++));do let sum+=i; done;echo $sum

image.png


八、awk數組

數組是一個包含一系列元素的表

格式如下:

                  abc[1]="libai"

                  abc[2]="lihei"

abc為數組名,[1][2]為數組下標,可以認為是數組的第一個元素,第二個元素,"libai""lihei"是元素的內容

舉例說明:

awk 'BEGIN{fan[0]="libai";fan[1]="lihei";print fan[0]}'
 
awk 'BEGIN{fan[0]="libai";fan[1]="lihei";print fan[1]}'
 

image.png

awk 'BEGIN{fan[0]="libai";fan[1]="lihei";for (i in fan)print i}'
 

image.png

awk -F: '{{fan[NR]=$1;}{print NR,fan[NR]}}' ceshi.txt
 

image.png

利用數組統計每個ip地址訪問量(編輯一個文件,該文件存儲ip地址)

image.png

awk '{array[$1]++} END {for(key in array) print array[key],key}' a|sort -r
 

關於array[$1]++ 

(1)awk在讀取第一行的時候,會讀取這個數組,此時的數組是這樣的,array["第一行的內容"]++

(2)此時該數組的值還沒有定義,但后面有運算符號++,所以awk會將數字0自動賦值給array["第一行的值"]做++運算,所以得到的值為1.

(3)在讀到與array["第一行的內容"]相同的時候繼續++運算,也就意味着,運算了多少次,就是出現了多少次。

image.png


九、awk函數

1、內鍵函數

(1)數值處理 rand() 返回0至1之間的一個隨機數

awk 'BEGIN{print rand()}'
 

image.png

從這張圖中我們發現了一個問題,通過使用rand函數生成隨機數,但是rand函數返回的值一直不變,所以我們需要配合srand函數

awk 'BEGIN{srand();print rand()}'
 

image.png

從這張圖中我們發現生成的隨機數產生了變化,但生成的隨機數都是小於1的小數,如果我們想要生成整數隨機數,我們可以利用int整數函數截取整數部分的值

awk 'BEGIN{srand();print 100*rand()}'
 
awk 'BEGIN{srand();print int(100*rand())}'
 

image.png

(2)字符串函數

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

舉例說明

awk '{print $0 length()}' abc.txt (每一行全部字符長度)
 

image.png

awk '{for(i=1;i<=NF;i++){print $i,length($i)}}' abc.txt(指定字符長度)
 

image.png

gsub(r,s[,t])基於r所表示的模式來匹配字符串t中的內容,將其所有被匹配到的內容均替換為s所表示的字符串

舉例說明

awk '{gsub("h","H",$1);print $0}' abc.txt
 

image.png

awk '{gsub("h","H",$0);print $0}' abc.txt
 

image.png

sub(r,s[,t]) 基於r所表示的模式來匹配字符串t中的內容,將其第一次被匹配到的內容替換為s所表示的字符串

舉例說明

awk '{sub("h","H");print $0}' abc.txt(只替換指定范圍第一次匹配到的符合條件的字符)
 

image.png

split(s,a[,r]) 以r為分隔符去切割字符串s,並將切割后的結果保存至a表示的數組中

舉例說明

awk -v aa="李大;李二;李三" 'BEGIN{split(aa,lishijiazu,";");for(i in lishijiazu){print lishijiazu[i]}}'
 

image.png

awk -v aa="cc;ff;dd;ee" 'BEGIN{split(aa,lishijiazu,";");for(i in lishijiazu){print lishijiazu[i]}}'
 

image.png

從上圖中我們發現數組元素輸出順序可能與字符串中字符的順序不同,我們可以采用下面的辦法

awk -v aa="cc;ff;dd;ee" 'BEGIN{ abc=split(aa,lishijiazu,";");for(i=1;i<=abc;i++){print i,lishijiazu[i]}}'
 

image.png

2、用戶自定義函數

函數是程序的基本組成部分,awk允許我們定義自己的函數,一個大的程序可以分為多個函數並且每個函數可以獨立測試

用戶自定義函數的一般格式為:

function function_name(argument1,argument2,...) { function body }
 

function_name是用戶定義函數的名稱,函數名稱應以字符的字母並且其余部分可以是數字,字母或下划線的任意組合,awk的保留字不能用作函數名字;函數可以接受以逗號分隔的多個參數,參數不是強制性的,我們也可以創建一個用戶定義的函數不帶任何參數;函數體由一個或多個awk語句組成。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM