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

linux 文本三劍客之awk

linux awk 練習

awk簡介


awk同sed、grep被稱為linux文本處理三劍客,都起源於行編輯器ed。awk繼承了行編輯器的特點,循環的讀取文本的每一行(或者是分隔符分割的每一段文本)直至文本結束,但是awk加入了段分割符的概念.將每次讀入的行進行再次分割.awk每次讀取的行都只是未經過awk語句處理的對象。或讀取行後會根據段分割符在將行分成多個對象。結構近似數組,然後進行指定語句的操作。作為一款報表生成器,作用是對對文本內容進行各種排版,進而格式化顯示。

awk有自己的語法,可以說是一款獨立的編程語言。 它對命令的處理可以稱為命令的解釋,或腳本語言的解釋 awk的語句書寫格式,屬於模塊化風格,特別是if,else語句表現的特別明顯有點類似於bash中的匿名函數。每個語句塊必須使用{}進行約束。

本文介紹了awk的常用用法及講解並添加示例以便加深理解,結尾準備了實戰練習以加強鞏固,請讀者自行按需閱讀,如有紕漏望請指出。

1、awk基本執行流程

2、awk基本格式

3、printf 用法及格式符、修飾符

4、awk中的控制語句

5、awk中的函數、變量及操作符

6、實戰練習



1、awk基本執行流程

①執行BEGIN語句塊中的內容,語句為可選語句.多用於執行變量的初始化,報表的頭輸出.

②從標準輸入或文件中讀取行分割符(-F定義的字符)分割的行進入內存,進行語句之前的條件匹配,在沒有條件時默認為符合執行條件.符合條件執行,不符合條件則嘗試匹配下一個語句之前的條件.直至所有條件匹配全部完成.當語句為空時默認執行{print $0}

③繼續讀取下一行,直至末尾

④執行END定義的語句內容,同樣也為可選語句.多用於報表的統計信息輸出.

2、awk基本格式及匹配條件

基本格式: awk選項 條件 語句 文件

選項:

-f 從文件中讀取處理命令
-F 指明行的段分隔符;默認為空白字符(一個或多個)
-v 自定義變量

條件

條件執行條件後的語句的要求。符合條件才可執行語句,條件即為對語句的判斷,可以使用正則匹配,基於正則的模式定界,字符串比較,可以使用算數條件表達式也可以是BEGINEND特殊條件

算數條件表達式最終返回運算結果,當運算結果為0,語句不執行。語句為空時默認執行{print

$0}。

例:正則_匹配正則匹配的每一行

awk ‘/^UUID/{print $1}‘/etc/fstab
匹配以UUID為開始的行,並執行{}中的語句。print $1
awk ‘!/^UUID/{print $1}‘ /etc/fstab
匹配以非UUID為開始的行,執行{}中的語句 。print $1

算數計算_條件為真該行才會被處理 ,條件 為假則不處理

awp -F: ‘$3>=1000{print $1,$3}‘ /etc/passwd
awp -F: ‘!$3>=1000{print $1,$3}‘ /etc/passwd
awk -F:‘(NR>=2&&NR<=10){print $1}‘

:字符串比較_比較結果為真進入循環

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

:行範圍_範圍內的行做處理 ,只支持模式定界(類似sed中的10,20地址定界不支持)

awk -F:‘/^root/,/^myuser/{print $1}‘

例:特殊條件_BEGIN/END

BEGIN:在開始之前顯示一次  
END:在文本處理完成 ,命令未完成時,執行一次 
awk ‘BEGIN{print "usernameID\n------------"}{printf "%10s:%-s" $1,$3}END{print "=========\n"}‘

例:特殊條件0,空。

awk -v aa="" ‘aa‘ /etc/passwd
變量aa的值為空 ,(語句為空執行默認語句)。但是條件為空,不執行默認語句。
awk -v aa=" " ‘aa‘ /etc/passwd
變量aa的值為‘ ’空格不為空執行默認語句
awk -v aa="0" ‘aa‘ /etc/passwd
變量aa的值為0,條件為最終值為0,默認語句不執行。
awk ‘!arr[$0]++’ dupfile 
以$0為下標建立數組,只打印文件不重復的行
awk -v aa=0 ‘aa++‘ /etc/passwd
aa初始值為0,第一條語句條件為a++,首先返回a的值在進行自加運算。所以打印第一行外所有行。awk中
默認對非關鍵字變量都賦值0,這個例子也可以寫成
awk  ‘aa++‘ /etc/passwd    打印效果相同。

3、printf 用法及格式符、修飾符

print類似bash中的echo打印給定字符並自動添加換行這裏不多說,printf對輸出格式可以自定義,用法需要大家註意。

語法:printf FORMAT,item1,item2,...

①必須提供FORMAT

②printf不會自動換行,若想換行需加換行符:\n

③FORMAT中需要依次分別為後面每一個item指定一個格式符,否則item不顯示。

格式符

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

修飾符

#[.#]:左邊#用於顯示寬度
       右邊的#表示小數點後的精度 
- : 左對齊,默認右對齊。
+ :  顯示數字的正負符號


4、awk中的控制語句

(1)、條件表達式

格式條件條件為真的語句條件為假的語句

例:

awk -F:‘{$3>=500?usertype="common":usertype="sysadmin";printf "%15s:%-s\n",$1,usertype}’
/etc/passwd

(2)、if-else

格式:

if(條件){語句}
if(條件){語句} else {語句}

例:

awk -F: ‘{if($3>1000) print $1,$3}‘ /etc/passwd
awk -F: ‘{if($3>1000){printf "普通用戶:%s",$1} else {printf "系統用戶:%s",$1}}‘

(3)、while循環

while (條件) {語句}
條件為真進入循環 ,條件為假退出循環。

例:

awk ‘/^[[:space:]]*linux/{i=1;while(i<NF){print $i,length($i);i++}}‘ /etc/grub2.cfg
awk ‘/^[[:space:]]*linux/{i=1;while(i<NF){if(length($i)>7){print $i,length($i)};i++}}‘ /etc/grub2.cfg

(4)、do-while循環

do{語句} while(條件)

首先執行do後面的語句。然後while中的條件進行判斷。條件符合繼續執行do後的語句。至少執行一次循環。

(5)、for循環

語法:for(expr1;expr2;expr3){statements}

例:

awk /[[:space:]]*linux/{for(i=1;i<=NF;i++){print $i,length($i)}} /etc/grub2.cfg

for可以實現遍歷數組元素 :

格式 :for (i in 數組名稱)遍歷時 i被賦值的是每個索引

5、awk中的函數、變量及操作符

函數:分為內建函數和自定義函數

內建函數

數值處理:rand()srand() 組合使用返回一個0至1之間的隨機數。

字符串處理:

length([s]):統計指定字符串的長度並返回。

sub(r,s[,t]):處字符串t可以是單純的字符串,變量,位置引用)t進行模式匹配,模式定義在r中,將模式r所匹配的內容替換成s中的內容,但是只進行1次替換

例:echo "2008:08:08:08 08:08:08:08" |awk ‘sub(/:/,"-",$0)‘

gsub (r,s,[t]):處理字符串t可以是單純的字符串,變量,位置引用)t進行模式匹配,模式定義在r中,將模式r所匹配的內容替換成s中的內容對於待處理的字符串t進行全局替換。

例:echo "[email protected]%9&Bdh7dq+YVixp3vpw"|awk ‘{gsub(/[^0-9]/,"",$0);print $0}‘

splita,array,[r]):r為分隔符,分割字符串a,並將分割後的字符串分別存入數組,數組的下1開始,第一個索引1,第二個索引為2.

例:netstat -tan |awk ‘/^tcp/{split($4,ip,":");a[ip[1]]++}END{for(i in a){print i,a[ip[1]]}}‘

int:將指定的內容轉換為整數類型

自定義函數

格式

function 函數名稱 (參數1 ,參數2 。。。){
語句1
語句2
return 數值
}

例:

#cat fun.awk
function max(v1,v2) {
v1>v2?var=v1:var=v2
return var
}
BEGIN{a=3;b=2;print max(a,b)}


變量:分為內建變量和自定義變量

內建變量:

FS:輸入的字段分割符,默認為空白字符

OFS:輸出的字段分隔符,默認也為空白字符。

RS:輸入時指明的行分割符,默認就是換行符,

ORS:輸出時的行分隔符,默認為換行符

NF :行中的字段數量

NR :行計數器 ,如果跟了多個文件編號會連續

FNR : 行數,各文件單獨計數 。

FILENAME : 當前的文件名

ARGC :命令行中的參數個數(awk也算一個參數)

ARGV :命令行中的參數 ,ARGV為數組參數為命自身及後跟隨的文件 ,語句不計入參數

自定義的變量

-v var=value

語句中直接定義多條與語句之間使用 ;分隔,每定義一個變量需要一個-v。

操作符

算數操作符 :實現算數運算x+y x-y x*y x/y x^y x%y

-x :將x 轉化為負數

+x :將字符串x 轉化為 數值

賦值操作符 :通常為變量賦值

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

++ --

比較操作符:> >= < <= != ==

模式匹配操作符:根據右側的模式進行匹配操作

~ : 是否由右側模式匹配

~是否由右側模式不匹配

邏輯操作符 :進行邏輯的運算與bash腳本中用法不同

&& :並且

|| :或者

!:非



6、awk實戰練習

(1)、統計/etc/fstab文件中每個文件系統類型出現的次數

awk ‘!/^#/{arr[$3]++}END{for(i in arr){print i,arr[i]}}‘ /etc/fstab

(2)、提取出字符串[email protected]%9&Bdh7dq+YVixp3vpw中的所有數字

echo "[email protected]%9&Bdh7dq+YVixp3vpw"|awk ‘gsub(/[^0-9]/,"",$0)‘

(3)、統計/etc/fstab文件中每個單詞出現的次數

awk ‘{i=1;while(i<=NF){word[$i]++;i++}}END{for(num in word){print num,word[num]}}‘ /etc/fstab

(4)、計算男生女生的總成績,平均成績

#cat 1.txt
mage    100    male
wang    80     male
zhang   70     female
li      100    female
#awk ‘{if($3=="male"){msum+=$2;mnum++}else{fesum+=$2;fenum++}}END{printf "%-5d %-.2f\n%-5d %-.2f\n",msum,msum/mnum,fesum,fesum/fenum}‘ 1






本文出自 “linux運維” 博客,請務必保留此出處http://arm2012.blog.51cto.com/2418467/1963105

linux 文本三劍客之awk