awk
awk****推薦去看朱雙印的博客“awk****從放棄到入門”理卑,寫的真的很好藐唠,本文的awk****就總結于它中捆。
awk其實是一門編程語音泄伪,它支持條件判斷蟋滴、數組津函、循環(huán)等功能尔苦。所以允坚,我們也可以把awk理解成一個腳本語言解釋器
1稠项、awk基礎
1.1展运、普通模式
awk 【option】 ‘program’ file1拗胜,file2
1.2埂软、特殊模式
1) BEGIN和END模塊只能有一個。中間的pattern匹配咖杂,可以有多個
NR==2{print 1}
2) BEGIN模塊诉字,代表awk在處理文本前要做的事壤圃。即使不接收文件名伍绳,僅僅使用BEGIN模塊打印冲杀,也能正常輸出
awk ‘BEGIN {print “111”,”222”}’
3) END模塊权谁,代表awk在處理文本后要做的事
awk ‘{print 2} END{print ‘333’,’444’}’test
1.3旺芽、內置變量
1.4运嗜、自定義變量
awk除了使用內置變量洗出,還可以自己定義變量翩活。
方法一:-v varname=value 變量名區(qū)分字符大小寫菠镇。-v:設置變量
方法二:在program中定義
1****利耍、-v ****定義
2****隘梨、在program****定義
2、printf
awk本身負責文本切割捻脖,printf動作則負責格式格式化文本可婶。在了解awk的printf動作前矛渴,需要首先了解printf命令
2.1曙旭、shell的printf命令
在shell中桂躏,echo和printf都是輸出文本的命令剂习。echo輸出的字符串鳞绕,會自動在末尾加上\n们何,
而printf不會冤竹。printf的作用是按照我們指定的格式輸出文本鹦蠕,所以\n钟病,也需要我們自己指定
echo與printf
注意看3肠阱,printf的優(yōu)勢就在于屹徘,可以用格式替換符缘回,幫我們處理一長串的str
替換符號
格式替換符
轉義字符
修飾符
“.5”表示整數的長度,不足用0補齊
例子
2.2、awk的printf動作
awk的printf動作與shell的printf命令很像,只是要注意幾點:
1) 使用printf動作輸出的文本不會換行诚啃,要自己手動加\n
2) 使用printf動作時始赎,“指定的格式”與“被格式化的文本”間造垛,要用“逗號”隔開
3) 使用printf動作五辽,“格式替換符”與“被格式化的文本”數量一一對應
例子
awk -v FS=':' 'BEGIN{printf "%-10s\t %s\n","用戶名稱","用戶ID"} {printf "%-10s\t %s\n",3}' /etc/passwd
用戶名稱 用戶ID
root 0
bin 1
3乡翅、awk模式(Pattern)
3.1髓迎、grep與awk的正則對比
grep ‘^root’/etc/passwd
awk ‘/^root/{print $0}’ /etc/passwd
3.2、awk正則的注意點
1)awk命令中的正則是“擴展正則表達式”
2)當使用{x,y}或[[:space]]尺铣,這種正則時凛忿,要加上參數—posix
3)注意對“\”和“.”轉義
3.3店溢、awk的行范圍模式
兩個正則的就是行范圍模式床牧,從正則1匹配的行開始,到正則2匹配的行結束
正則匹配符
3.4著蛙、例子
4、awk動作總結
4.0暂吉、動作拆分
上圖的動作分為兩個部分:
1) 紅線標注:最外側的括號“{}”阎肝》缣猓“組合語句”類型的動作沛硅,將多個代碼組合成代碼塊
2) 藍線標注:“print $0”摇肌。print是“輸出語句”類型的動作
例子
4.1、if動作
如果if對應的{}肯适,只有一條命令框舔,可以省略{}
4.2刘绣、for動作
4.3、while動作
4.4、do…while動作
do…while循環(huán)無論是否滿足while的條件绢馍,都會先執(zhí)行一次do里的命令
打印一遍test
打印5遍test
4.5、cotinue和break
1~5瓷耙,不打印3
打印1~3
4.6、exit
awk中搁痛,exit表示跳過后序所有動作长搀,直接執(zhí)行END內的命令。如果沒有END模式鸡典,則會直接結束awk命令
只打印1
不會打印$0
4.7源请、next
next的作用是跳過當前行。直接從下一行 開始處理
跳過第2行
5彻况、awk數組
5.1、基礎概念
1)awk中的數組是一個使用字符串作為下標的“關聯數組”纽甘。
2)我們在使用時良蛮,可以用 數字/字符串 作為下標,不過使用數字作為下標時悍赢,awk默認會把“數字”下標轉換為“字符串”决瞳。
3)在awk中,元素的值可以設置為“空”泽裳。
4)當一個元素不存在于數組時瞒斩,如果我們直接引用這個不存在的元素,awk會自動創(chuàng)建這個元素涮总,并且默認為這個元素賦值為“空字符串”
5)在awk中胸囱,判斷數組中元素是否存在,用“if(下標 in 數組名)”瀑梗。即判斷數組中是否有key
6)使用split函數生成的數組烹笔,下標默認是從1開始的
5.2、基本操作
創(chuàng)建數組抛丽,直接創(chuàng)建就可以
刪除數組中的元素
awk ‘BEGIN{ …谤职;delete huluwa[0]}’
刪除整個數組
awk ‘BEGIN{ …;delete huluwa}’
for循環(huán)有序遍歷數組亿鲜。只有下標是數字時允蜈,通過下標的遞增,才能有序遍歷
awk ‘BEGIN{ …蒿柳;for (i=1;i<=3;i++){print i饶套,huluwa[i];} }’
for循環(huán)無序遍歷數組。因為awk數組本身是無序的關聯數組
awk ‘BEGIN{ …垒探;for (i in huluwa){print i妓蛮,huluwa[i]} }’
實例應用——統計某文件$1 重復出現的次數
awk ‘{count[$1]++} END{ for (i in count ) {print i,count[i]} }’ file
實例應用——統計某文本人名出現次數
awk ‘{ for (i=1;i<=NF;i++) {count[$i]++} } END{ for (a in count) {print a,count[a]} }’
6、awk內置函數
6.1圾叼、算術函數
rand函數蛤克,srand函數捺癞,int函數
rand函數固定打印了0.237788,srand函數固定打印1构挤,兩者合用髓介,可生成小于1的隨機數
rand函數
awk 'BEGIN{print rand()}'
0.237788
srand函數
awk 'BEGIN{print srand()}'
1
生成小于1的隨機數
awk 'BEGIN{srand();print rand()}'
0.319498
通過隨機數乘100,在通過int函數取整儿倒,生成0~100間的隨機數
awk 'BEGIN{srand();print int(100*rand())}'
76
6.2版保、字符串函數
gsub函數,sub函數
這兩個函數用于替換某些 文本
awk ‘{ gsub (“old”夫否,“new”彻犁,0}’file
awk ‘{ gsub (“[a-z]”凰慈,“new”汞幢,0}’file
gsub將指定范圍內匹配的字符全部替換為新字符
sub用法與gsub一樣微谓,但只替換匹配范圍內第一次匹配到的字符
比如某文件就一行森篷,$1=aaa。
gsub(“a”豺型,“b”)仲智,則0
sub(“a”钓辆,“b”),則$1=baa肴焊。
length函數
length函數可獲取指定字符串的長度前联。不指定參數,默認為$0
awk ‘{ for (i=1娶眷;i<=NF似嗤;i++) {print i)} }’file
index函數
獲取指定字符串位于整個字符串中的位置
awk ‘{print index($0届宠,“LEE”)}’file
0
7
0
index函數在每一行中查找LEE烁落,如果該行沒有,返回0豌注,該行有伤塌,返回位置
split函數
split函數可以切割字符串,幫我們動態(tài)生成數組幌羞。生成的數組下標從1開始
將ts以“;”分隔寸谜,并將分隔后的str保存到huluwa數組中
awk –v ts=”one;two;three”‘BEGIN{ print split(ts,huluwa,”竟稳;”)}’
split函數的返回值就是數組長度
split(ts,huluwa,”属桦;”) == 3
6.3熊痴、排序函數
asort函數
asort函數根據數組的value值進行排序
asort排序后,原有key將被數字替代
awk 'BEGIN{ t["a"]=66;t["b"]=88;t["c"]=35 ; asort(t) ; for (i in t){print i,t[i]} }'
1 35
2 66
3 88
asort排序時聂宾,新建一個數組果善。t[]不變竖席,新創(chuàng)了new[]
awk 'BEGIN{ t["a"]=66;t["b"]=88;t["c"]=35 ; asort(t,new) ; \
for (i in new){print i,new[i]} }'
asort函數的返回值就是數組的長度
asort(t,new)==3
asorti函數
asorti函數會對原數組的key排序浴骂,然后將key作為value生成一個新數組
awk 'BEGIN{ t["a"]=66;t["b"]=88;t["c"]=35;asorti(t,new);for (i in new){print i,new[i]} }'
1 a
2 b
3 c
通過asorti排列原數組
awk 'BEGIN{ t["a"]=66;t["b"]=88;t["c"]=35;asorti(t,new);\
for (i in new){print i,new[i]菠剩,t[new[i]] } }'
1 a 66
2 b 88
3 c 35
7纪他、三元運算與打印奇偶行
7.1鄙煤、三元運算
if…else判斷用戶類型
awk –F : ‘{ if($3<500){usertype=“系統用戶”}else{ usertype=“普通用戶”};\
print $1茶袒,usertype }’/etc/passwd
三元運算符替換if…else
awk –F : ‘{ usertype=$3<500梯刚?“系統用戶”: “普通用戶”;\
print $1薪寓,usertype }’/etc/passwd
l $3<500:條件判斷
l ?”系統用戶”:為真亡资,則“系統用戶”賦給usertype
l :“普通用戶”:為假,則“普通用戶”賦給usertype
三元運算符統計“系統用戶”和“普通用戶”數量
awk -F: '{$3<500?a++:b++}END{print a,b}' /etc/passwd
7.2向叉、打印奇偶行
打印奇數行
awk ‘a=!a’flie
打印偶數行
awk ‘!(a=!a)’flie
解析:
我們知道awk的正則匹配是
/
但如果我們不加print動作锥腻,僅僅有正則,那么會默認打印$0母谎。
awk ‘/正則/’file
而在awk中瘦黑,非0/非空str表示“真”。0/空表示“假”
注意销睁,這不是正則供璧,‘2’不為0/空,打印file所有
awk '2' file
所以’a=!a’
1) a沒有定義冻记,初始化a=‘’睡毒,a為“假”
2) !a為“真”
3) a=!a,a變?yōu)椤罢妗比呃酰蛴〉?行
4) !a又變?yōu)椤凹佟毖莨耍淮蛴〉?行
‘!(a=!a)’
1)a=!a為真,!(a=!a)為假隅居,不打印 第1行
2)a=!a為假钠至,!(a=!a)為真,打印第2行
8胎源、參考文檔
awk從放棄到入門 (http://www.zsythink.net/?s=awk)
awk用法(使用入門) (https://www.cnblogs.com/emanlee/p/3327576.html)
官方文檔 (https://www.gnu.org/software/gawk/manual/html_node/index.html#SEC_Contents)