1. 程式人生 > >文本處理三劍客之awk

文本處理三劍客之awk

awk

文本處理三劍客之awk

awk:

報告生成器,格式化文檔輸出;

awk(gawk):pattern scanning and processing language

格式:awk [options...] 'program' file

program: [/PATTERN/]{ACTION statement;...}

PATTERN:決定動作語句何時觸發以及通過什麽事件來觸發(BEGIN/END);

ACTION statement:對數據進行特定的處理,通常放在{}中(print/printf);


基本概念:

分隔符(輸入分割符,輸出分隔符)

輸入分割符:

awk對數據進行處理時,會根據特定的標識符對數據進行分段處理,該標識符稱為輸入分隔符(默認為空白字符);

輸出分隔符:

awk在處理完數據後,會以特定標識符對各字段進行輸出;

記錄:由換行符分割的數據中的一行,稱為一條記錄,通常用$0表示;

字段:經過分隔符分割後的每一個數據分段(field),通常用$N表示(N為除0外的數字);



awk的工作原理:

1):首先執行Begin{action statement}語句塊中的語句;

2):其次,從文件或標準輸入中讀取一行,根據Pattern匹配的結果執行action的內容,重復此操作,直到完畢;

3):最後,執行End{action statement}語句塊中的語句;

註意:

1)begin語句在awk處理數據前執行,常用於生成表頭(該語句可省略)

2)end語句在awk處理完所有數據後執行,用於數據匯總(該語句可省略)

3)Pattern語句是最重要的部分,不可省略,但action可省略,默認執行print操作;

4)awk在執行Pattern語句塊時,默認循環遍歷數據中的各記錄;


常用選項:

-f:--file program-file:從指定文件中加載program語句塊;

-F:--filed-sparator fs:指定字段的輸入分隔符;

-V:--assign var=value:用於聲明自定義變量並為其賦值;



awk的常用用法:

1.變量:(內置變量,自定義變量)

內置變量:

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

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

例:

~]# awk -v FS=':' -v OFS=':' '{print $1,$2}' /etc/group


RS:輸入記錄分隔符,默認為換行符(即使定義了記錄分割符,原有的換行符依舊有效);

ORS:輸出記錄分隔符,默認為換行符(即使定義了記錄分割符,原有的換行符依舊有效);

例:

~]# awk -v RS=':' '{print $1,$2}' /etc/group


NF:每一行字段的總數;

例:

~]# awk -F: '{print NF}' /etc/group


NR:列出文件行的總行號;

例:

~]# awk -F: '{print NR}' /etc/group


FNR:對不同的文件統計文件行的行號;

例:

~]# awk -F: '{print FNR}' /etc/group /etc/passwd

FILENAME:當前正在被使用的文件的文件名;

例:

~]# awk -F: 'END{print FILENAME}' /etc/group /etc/passwd

       ARGC:命令行中參數數量(不包括Option中和Program中的參數)

例:

~]# awk -F: 'END{print ARGC}' /etc/group /etc/passwd /etc/fstab


ARGV:由命令行所有參數構成的數組

例:

~]# awk -F: 'END{print ARGV[2]}' /etc/group /etc/passwd /etc/fstab

自定義變量:

定義方式:-v var_name

例子:

# awk -v var='你好' -F: '{print $1,":",var}' /etc/passwd

2.常用的action:

print:

格式:print item1,item2....

註意:1)各item之間需使用","進行分割

2)item可以是字符串,數字,變量,當前記錄中的字段,也可是awk表達式(省略則輸出整行)

例:

~]# awk -F: '{print $1,$3,$6}' /etc/passwd


printf:format and print ,以特定的格式輸出結果;

格式; ;printf "FORMAT" item1,item2....

註意:1)必須給出合適的輸出格式

2)默認不自動換行,需給出"\n"

3)FORMAT中需為後面的每個item指定格式化符號;

常用的FORMAT:

%c:以ACSII碼表中的內容顯示字符信息;

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

%e,%E:以科學記數法顯示數字,浮點類型;

%f,%F:顯示十進制數字的浮點形式

%g,%G:以科學記數法顯示浮點數字

%v:顯示無符號十進制數字

%s:顯示字符串

%x,%X:顯示無符號的十六進制數

%%:顯示%

修飾符:

#[.#]:第一個數字用來控制顯示寬度;第二個數字表示小數點的精度;

如:%5s, $8.3f

-:表示采用左對齊方式顯示;默認是右對齊;

+:顯示數字的正負符號;


示例:

技術分享圖片



3.操作符:

算術運算操作符:

雙目運算符:

x+y, x-y, x*y, x/y, x^y, x%y

單目運算符:

-x:將正整數轉換為負整數;

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


字符串操作符:

無任何操作符號時,即為字符串連接操作;


賦值操作符:

=, +=, -=, *=, /=, ^=, %=,++, --


比較操作符:

==, !=, >, >=, <, <=


模式匹配操作符:

~:操作符左側的字符串是否能夠被右側的PATTERN所匹配;

!~:操作符左側的字符串是否不能被右側的PATTERN所匹配;

例:

~]# awk -F: '$1~/root/{print $0}' /etc/group




邏輯運算操作符:

&&

||

|

例:

~]# awk -F: '$3>100&&$3<200{print $0}' /etc/group



條件表達式:

selector(condition)?if-true-expression:if-false-expression

例:

~]# awk -F: '{$3>100?usertype="common":usertype="super";printf "%-20s: %-5s\n",$1,usertype}' /etc/passwd



4.PATTERN部分:

1) empty:空模式,不加區分地處理文件的每一行;

2) [!]/REGEXP/:僅處理[不]能被PATTERN匹配到的行;

例:

~]# awk -F: '/^r/{print $0}' /etc/passwd


3) 關系表達式:

$3>=1000

$NF~/bash/

4) 行域,行範圍:

關系表達式的邏輯運算:FNR>=10&&FNR<==20

例:

~]# awk 'NR>=15&&NR<=20{print NR,$0}' /etc/passwd


/REGEXP1/,/REGEXP2/:

從被REGEXP1匹配的行開始,直到被REGEXP2匹配的行結束,這期間的所有行;凡是屬於此類的匹配結果,有多少組就顯示多少組;

示例:

~]# awk -F: '/^r/,/^a/{print NR,$0}' /etc/passwd


5) BEGIN/END模式:

BEGIN{}

僅在開始處理文件中的第一行文本數據之前執行一次的語句塊;多用於輸出特定格式的表頭信息;

例:

~]# awk -F: 'BEGIN{printf "%20s %10s %20s\n","USERNAME","USERID","SHELL"}NR>=15&&NR<=20{printf "%20s %10s %20s\n",$1,$3,$7}' /etc/passwd


END{}

僅在文本處理完成但awk命令尚未退出時執行一次的語句塊;多用於數據信息的匯總;

例:

~]# awk -F: 'BEGIN{printf "%20s %10s %20s\n","USERNAME","USERID","SHELL"}NR>=15&&NR<=20{printf "%20s %10s %20s\n",$1,$3,$7}END{print "-------\n",NR " users"}' /etc/passwd


註意:

1) BEGIN語句塊,PATTERN語句塊和END語句塊的順序,通常來講是:BEGIN{}PATTERN{}END{}

2) BEGIN語句塊和END語句塊是可選的,但PATTERN語句塊必須給出;


5.常用的ACTIONS

1) 表達式(Expression)

2) 組合語句(Compound Statements)

3) 輸入語句(Input Statements)

4) 輸出語句(Output Statements)

5) 控制語句(Control Statements)


6.控制語句:

if (condition) statement [ else statement ]

while (condition) statement

do statement while (condition)

for (expr1; expr2; expr3) statement

for (var in array) statement

break

continue

exit [ expression ]

switch (expression) { case value|regex : statement ... [ default: statement ] }

next


1) if ... else:

語法:

if (condition) statement [ else statement ]

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


示例:

~]# awk -F: '{if($3>=1000){print "CommonUser:",$1}else{print "Sysuser:",$1}}' /etc/passwd

~]# awk fstab'/^[^#]/{if(NF==6){print}}' /etc/passwd

分析磁盤上各個文件系統的空間利用率:

~]# df -h | awk -F% '/^\/dev/{print $1}' | awk '{if($NF>=80){print $1}}'


2) while循環:

語法:

while (condition) statement

使用場景:

a.對一行內的多個字段逐一做相同或類似的操作處理時使用;

b.對數組中的各數組元素做遍歷處理時使用;


while循環的特點:條件為真,進入循環;一旦條件為假,則退出循環;


例:

~]# awk '{i=1;while(i<=NF){print $i,length($i);i++}}' testfile


3) do ... while語句:

語法:

do statement while (condition)


意義:與while循環相同,但statement語句段至少被執行一次;


4) for循環:

語法:

for (expr1; expr2; expr3) statement

expr1:variable assignment,變量賦初值;

expr2:circle condition,循環條件判斷;

expr3:interation process,變量值修正方法;


示例:

~]# awk '{for(i=1;i<=NF;i++){print $i,length($i)}}' testfile


for (var in array) statement


5) switch ... case語句

語法:

switch (expression) { case value|regex:statement;case value2|regex2:statement;... [ default: statement ] }


使用場景:

用於進行字符串比較判斷;


6) break和continue語句:

break [n]

continue


註意:其使用場景是行內多個字段間做循環時的循環控制方式;

例:

~]# awk '{for(i=1;i<=NF;i++){if(length($i)<5){continue}else{print $i,length($i)}}}' testfile


7) next語句:

在awk處理數據時,提前結束對當前行的處理,而直接開始處理下一行;


例:

~]# awk -F: '{if($3%2==1){next}else{print $1,$3}}' /etc/passwd

8.數組——Array

用戶自定義的數組,一般使用關聯數組:array_name[index_expression]

註意:

1) index_expression可以使用任意的字符串,但字符串必須放在雙引號中;

2) 支持弱變量數組,即:如果某數組元素事先不存在,當引用該元素時,awk會自動創建此元素,並為此元素賦"空字符串"作為其初始值;


示例:

~]# awk 'BEGIN{name["leader"]="zhangsan";name["mem1"]="lisi";name["mem2"]="bob";print "Leader:",name["leader"],"Member:",name["mem1"],name["mem2"]}'


~]# awk 'BEGIN{name["leader"]="zhangsan";name["mem1"]="lisi";name["mem2"]="bob";for(i in name){print name[i]}}'


查看當前系統上所有服務的不同TCP狀態的連接數量的統計:

~]# netstat -nalt | awk '/^tcp\>/{state[$NF]++}END{for(stat in state){printf "%15s: %-10d\n",stat,state[stat]}}'


用於統計本服務器web站點的每個用戶的請求數值:

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


用於統計本服務器web站點的UV值:

~]# awk '{ipaddr[$1]++}END{for(ip in ipaddr){print ip,ipaddr[ip]}}' /var/log/httpd/access_log | wc -l


9.函數:

內建函數:

數值函數:Numeric Functions

rand():返回一個介於0到1之間的隨機數;

sqrt():對於指定的數值進行開二次方;


字符串函數:String Functions

length():計算給定字符串的長度;

gsub(r, s [, t]):以r表示的模式來查找t表示的字符串中能夠被匹配的內容,並將所有出現的內容替換成s表示的內容;

split(s, a [, r [, seps] ]):以seps作為分隔符,利用r表示的模式進行匹配,將s代表的字符串分割之後,保存在a表示的數組中;


自定義函數:

function name(parameter list) { statements }





























文本處理三劍客之awk