有awk入門教程嗎?
答:本文邀請kitman來回答,理論結合實際為你獻上奉上后臺必備技能-awk入門教程~
首先說明,awk的數值只有雙精度浮點型。awk是一種非常強大文本處理工具,可以相當于一個數據庫來使用。
$digit 代表第幾個字段,字段之間的間隔默認是空格或者\t,多個連續的間隔算一個間隔,$0代表這一行
awk命令的基本格式awk 'awk程序語句' 輸入文件1 輸入文件2 …
awk 程序語句的基本格式pattern1 {action1} pattern2 {action2} …
pattern是篩選的條件,支持||、&&、! 這些條件組合
注:pattern可為空,即每一行,pattern還支持正則表達式,/正則內容/ {action}
eg:
awk '$6 != 0{print $0}' file1
即這一行的第六個字段不等于0,則打印這一行
awk的內置變量NR 記錄當前已經讀取的行數(不是輸出的行數)
FNR 作用域是當前文件的NR
NF 記錄當前行的字段數
trick:當多個輸入文件時,NR==FNR 即這一行在第一個文件中,NR>FNR即這一行不在第一個文件中。
awk的內置特殊patternBEGIN:匹配第一個輸入文件第一行之前的位置
END:最后一個輸入文件最后一行之后的位置
awk的actionaction里面可以定運算,支持+ - × / % 五種運算。變量直接只用,不需要聲明;
action中如果有多條語句,那么可以用;隔開
awk中只有兩種類型:數值、字符串。可以變量可以使用字符串的拼接,使用空格隔開。
eg:
test.awk:
1 2 3 4
2 3 18 2
a b 17 1
awk '$3 > 15 {count=count+1} END {print count}' test.awk
2
awk '$3 > 15 {count=count+1;var=count "haha";print var}' test.awk
1haha
2haha
awk '$3 > 15 {count=count+1;var=count "_haha";print var}' test.awk
1_haha
2_haha
即計算第三個字段大于15的行數,最后打印出來
awk的數組與控制語句awk支持數組,和使用一般的變量一樣,不需要聲明,直接a[下標]=value就可以了。這個下標可以是字符。
awk還支持一般編程語言中常見的控制結構if、while、for,和c中的寫法一樣。
if(){}else{}
while(){}
for( ; ;){}
eg:
逆序打印行,這里使用了printf,它的用法和c中的printf差不多,可以用于格式化的輸出,默認不輸出換行。
awk'{line[NR]=$0} END{i=NR;while(i>0) {printf line[i]"\n";i=i-1}}' test.awk
a b 17 1
2 3 18 2
1 2 3 4
awk的選項awk -F 指定輸入文件字段的分隔符
eg:
test2.awk:
1:2 3 4
2:3 18 2
a:b 17 1
awk -F ":" '{print $2}' test2.awk
2 3 4
3 18 2
b 17 1
把:換成\t之后:
awk -F ":" '{print $2}' test2.awk
空行
空行
空行
注:分隔符是空格時,\t也是分隔符;但指定\t是分隔符時,空格不是分隔符
awk的內置函數split(“被切割的字符串”,數組名,”分隔符”)
toupper() 替換成大寫
tolower() 替換成小寫
gsub() 全局替換
length() 計算字符串的長度
eg:
awk '{print length($3)}' test.awk
1
2
2
大例子業務場景
收藏排行榜
從收藏存量記錄、和取消收藏存量記錄中,提取出收藏排行榜
存量記錄中,$1是用戶uin,$6是漫畫id
思路:
1、把收藏存量記錄中的$1_$6作為一個key,放進一個map,值是收藏時間
2、再從取消收藏記錄中,取$1_$6,對比時間,然后刪除(相當于合并狀態),然后輸出結果
3、把數據結果用map記錄,計數,輸出結果
4、把數據結果用sort逆序按數字大小排,然后把次數cut掉
對應的腳本語句:
awk 'NR==FNR{a[$1"_"$6]=$7} NR>FNR{key=$1"_"$6;if((key in a)&&(a[key] < $7)){delete a[key]}} END{for(i in a){print i}}' allcollect03 allcancel03 | awk -F"_" '{b[$2]=b[$2]+1;} END{for(i in b){print i"\t"b[i]}}' | sort -r -n -k 2 | cut -f '1'