awk(gawk):報告生成器,格式化文本輸出:awk,gawk

目前創(chuàng)新互聯(lián)公司已為超過千家的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)頁空間、網(wǎng)站托管、企業(yè)網(wǎng)站設(shè)計、仁布網(wǎng)站維護等服務(wù),公司將堅持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。
基本用法:gawk [options]‘program’ FILE ...
program: PATTERN{ACTION STATEMENT};可以有多個,語句之間用分號分隔
print,printf
選項:
-F:指明輸入數(shù)據(jù)時用到的字段分隔符
-v var=value:自定義變量;
變量:
1)內(nèi)建變量
FS:input field seperator(輸入字段分隔符,默認為空白字符)
#awk -v FS=':' '{print $1}' /etc/passwd
#awk -F: ‘{print $1}’ /etc/passwd(這個命令和上面的命令效果是一樣的)
注:使用FS可以一次使用多個字符做為分隔符;例:awk -v FS="[,:]" '{print $3,$1,$2}' d.txt
OFS:output field seperator(輸出字段分隔符,默認為空白字符)
#awk -v FS=':' -v OFS=':' '{print $1,$3,$7}' /etc/passwd
RS:input record seperator,輸入時的換行符;
ORS:output record seperator,輸出時的換行符;
NF:number of field,每一行字段數(shù)量
{print NF},{print $NF}(在awk中引用變量不需要加$符號)
一行中的最后一個字段用$NF表示
NR:number of record,處理過的行數(shù)
#awk ‘{print NR}’ /etc/fstab
FNR:每一個文件處理過的行數(shù)
#awk ‘{print FNR}’ /etc/fstab /etc/issue
FILENAME:當前正在處理的文件的文件名
#awk ‘{print FILENAME}’ /etc/fstab
ARGC:命令行參數(shù)的個數(shù)
#awk 'BEGIN{print ARGC}' /etc/fstab
ARGV:數(shù)組,保存的是命令行所給定的各參數(shù)
#awk 'BEGIN{print ARGV[0]}' /etc/fstab
2)自定義變量
-v var=value
變量名區(qū)分字符大小寫;
#awk -v test='Hello gawk' 'BEGIN{print test}'
在program中直接定義
#awk 'BEGIN{test="Hello gawk";print test}'
操作符:
算術(shù)運算操作符:
x+y,x-y,x*y,x/y,x^y(次方),x%y
-x
+x:轉(zhuǎn)換為數(shù)值
字符串操作符:默認為沒有符號的操作符:表示字符串連接
賦值操作符:
=,+=,-=,*=,/=,%=,^=
比較操作符:
>,>=,<,<=,!=,==
模式匹配符:
~:是否匹配
!~:是否不匹配
邏輯操作符:
&&:與
||:或
!:非
函數(shù)調(diào)用:
function_name(argu1,argu2,...)
條件表達式:
selector?if-true-expression:if-false-expression
#awk-F: '{$3>=1000?usertype="Common User":usertype="SysadminUser";printf "%15s:%-s\n",$1,usertype}' /etc/passwd
printf格式化輸出:
格式化輸出的命令:printf FORMAT,item1,item2,...
(1)FORMAT必須要給出
(2)Printf不會自動換行,如果需要換行,需要顯式給出換行控制符,
(3)FORMAT中需要分別為后面的每個item指定一個格式化符號
格式符:
%c:顯示字符的ASCII碼;
%d,%i:顯示十進制整數(shù);
%e,%E:科學計數(shù)法計數(shù)顯示
%f:顯示為浮點數(shù);
%g,%G:以科學計數(shù)法或浮點形式顯示數(shù)值;
%s:顯示字符串;
%u:無符號整數(shù);
%%:顯示%自身;
修飾符:
#[.#]:第一個數(shù)字用來控制顯示的寬度:第二個#表示小數(shù)點后的精度,可以省略
#awk -F: '{printf "Username:%20s UID:%d\n",$1,$3}' /etc/passwd
-:左對齊
#awk -F: '{printf "Username:%-20s UID:%d\n",$1,$3}' /etc/passwd
+:顯示數(shù)值的符號,負數(shù)顯示為-,正數(shù)顯示為+號
#awk -F: '{printf "Username:%20s UID:%+d\n",$1,$3}' /etc/passwd
模式匹配:
1)empty:空模式,匹配每一行;
2)/regular expression/:僅處理能夠被此處的模式匹配到的行
#awk '/^#/{print}' /etc/fstab
#awk '!/^#/{print}' /etc/fstab
3)relational expression:關(guān)系表達式,結(jié)果有”真“有“假”:結(jié)果為”真“才會被處理:真:結(jié)果為非0值,非空字符串;
#awk -F: '$3>=1000{print $1,$3}' /etc/passwd
#awk -F: '$3<=1000{print $1,$3}' /etc/passwd
#awk -F: '$NF=="/bin/bash"{print $1,$NF}' /etc/passwd
#awk -F: '$NF~/bash$/{print $1,$NF}' /etc/passwd
4)line ranges:地址定界(行范圍)
#awk -F: '/^root/,/^liu/{print $1}' /etc/passwd
注意:不支持直接給出數(shù)字的格式
#awk -F: '(NR>=2&&NR<=10){print $1}' /etc/passwd
5)BEGIN/END模式
BEGIN{}:表示僅在開始處理文件中每一行文本之前執(zhí)行一次的程序;
END{};表示僅在文本處理完成之后,命令結(jié)束之前執(zhí)行一次的程序;
條件判斷,循環(huán):
條件判斷:
if(condition){statements}
例:#awk -F: '{if($3>=1000) print $1,$3}' /etc/passwd
if(confition){statements} else {statements}
例:#awk -F: '{if($3>=1000) {printf "Commono user:%s\n",$1} else {printf "root orSysuser:%s\n",$1}}' /etc/passwd
循環(huán):
while(condition) {statements}:條件為“真”,進入循環(huán):條件為“假”,退出循環(huán)
例:#awk -v i=1 'BEGIN{while(i<=4){print i;++i}}'
for(expr1;expr2;expr3) {statements}
例:#awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) {print $i,length($i)}}' grub2.cfg
for(var in array) {for-body}:常用于遍歷數(shù)組中的元素
例:#netstat -tan | awk '/^tcp\>/{state[$NF]++}END{for(i in state) {print i,state[i]}}'
#awk '{ip[$1]++}END{for(i in ip) {print i,ip[i]}}' /usr/logcal/nginx/logs/access.log
跳出循環(huán):
break:跟出整個循環(huán)
continue:跳出當前循環(huán),進入下一個循環(huán)
next:提前結(jié)束對本行的處理,直接進入下一行
例:#awk -F: '{if($3%2!=0) next;print $1,$3}' /etc/passwd
數(shù)組:
關(guān)聯(lián)數(shù)組是awk一個獨特的特征,它的一個強大的功能就是可以使用字符串作為一個數(shù)據(jù)的下標
Index-erpression:
若某數(shù)組事先不存在,則在使用時直接創(chuàng)建,并將其初始化為空的數(shù)組;
可使用任意字符串作為下標;字符串要使用雙引號;
若要判斷數(shù)組中是否存在某元素,要使用”index in array“格式進行:
若要遍歷數(shù)組中的每個元素,要使用for循環(huán);
for(var in array) {for-body}
注意:var會遍歷array的每個索引;
刪除數(shù)組中的元:
delete array[subscript]
函數(shù):
awk的內(nèi)置函數(shù)可以分為兩組:算術(shù)函數(shù)和字符串函數(shù)
1)內(nèi)置函數(shù)
數(shù)值處理:
rand():返回0和1之間一個隨機數(shù);
字符串處理;
length([s]):返回指定字符串的長度
sub(r,s,[t]):以r表示的模式來查找t所表示的字符中的匹配的內(nèi)容,并將其第一次出現(xiàn)替換為s所表示的內(nèi)容;
gub(r,s,[t]):以r表示的模式來查找t所表示的字符中的匹配的內(nèi)容,并將其全部替換為s所表示的內(nèi)容;
split(s,a[,r]):以r為分隔符切割字符s,并將切割后的結(jié)果保存至a所表示的數(shù)組中;
#netstat -tan | awk '/^tcp\>/{split($5,ip,":");count[ip[1]]++}END{for (i in count) {print i,count[i]}}'
getline函數(shù):
getline函數(shù)的作用是從文本中讀取內(nèi)容,也可以從管道中接收內(nèi)容
getline函數(shù)的用法比較特殊,不能使用getline(),它的語法不允許有圓括號,只能使用getline
從文件中讀取內(nèi)容:getline < "a" --> 從文件a中讀取內(nèi)容,小于號表示重定向,不能理解為小于號
將讀取的內(nèi)容賦給一個變量:getline name < "a"
2)自定義函數(shù)
練習:
1.統(tǒng)計/etc/fstab文件中每個文件系統(tǒng)類型出現(xiàn)的次數(shù);
2.統(tǒng)計指定文件中每個單詞出現(xiàn)的次數(shù);
3.統(tǒng)計下面語句中,每個單詞及字符出現(xiàn)的個數(shù)
the squid project provides a number of resources toassist users design,
implement and support squid installations. Please browsethe documentation
and support ections for more infomation
4.統(tǒng)計grade.txt中的分數(shù)的平均數(shù)
mona 70 77 85 83 70 89
john 85 92 78 94 88 91
andrea 89 90 85 94 90 95
jasper 84 88 80 92 84 82
dunce 64 80 60 60 61 62
ellis 90 98 89 96 96 92
5.在問題4的基礎(chǔ)上統(tǒng)計grade.txt中班級平均分數(shù),并以A,B,C,D為同學平均分做出分類并統(tǒng)計?
6.文件test中有如下內(nèi)容:
zhangsan 80
lisi 81.5
wangwu 93
zhangsan 85
lisi 88
wangwu 97
zhangsan 90
lisi 92
wangwu 88
要求輸出格式:(average:平均成績,total:總成績)
name#######average#######total
zhangsan xxx xxx
lisi xxx xxx
wangwu xxx xxx
答案:
1.
#awk '!/^#/{fs[$3]++}END{for(i in fs) {print i,fs[i]}}' /etc/fstab2.
#awk '{for(i=1;i<=NF;i++){count[$i]++}}END{for(i in count) {print i,count[i]}}' /etc/fstab3.
統(tǒng)計字符出現(xiàn)的次數(shù)
#grep -o "\w" c.txt | awk '{s[$1]++}END{for (key in s) print key,s[key]}'統(tǒng)計單詞出現(xiàn)的次數(shù)
#awk 'BEGIN{RS="[ .,]+"}{words[$1]++}END{for(i in words){print i,words[i]}}' c.txt4.
[root@localhost ~]# cat 8.awk
{
total=0
for(i=2;i<=NF;i++){
total += $i
avg=total/(NF-1)
}
print NR,$1,avg
}5.
[root@localhost ~]# cat grades.awk
BEGIN{OFS="\t"}
{
total=0
for(i=2;i<=NF;i++){
total += $i
avg=total/(NF-1)
}
student_avg[NR]=avg
if(avg>=90) grade="A"
else if(avg>=80) grade="B"
else if(avg>=70) grade="C"
else if(avg>=60) grade="D"
else grade="F"
++class_grade[grade]
}
END{
for(x=1;x<=NR;x++){
class_avg_total += student_avg[x]
print student_avg[x]
}
class_average=class_avg_total/NR
for(x=1;x<=NR;x++){
if(student_avg[x]>=class_average)
++above_average
else
++below_average
}
print ""
print "班級平均分數(shù):",class_average
print "大于平均分數(shù)有:"above_average" 位同學!"
print "低于平均分數(shù)有:"below_average" 位同學!"
for(letter_grade in class_grade){
print letter_grade":" class_grade[letter_grade] | "sort"
}
}6.
[root@localhost ~]# awk 'BEGIN{print "name\taverage\ttotal"}{a[$1]+=$2;b[$1]++}END{for(i in a){print i"\t"a[i]/b[i]"\t"a[i]}}' test
name average total
zhangsan 85 255
wangwu 92.6667 278
lisi 87.1667 261.5
解析:
a[$1]+=$2:把第一列作為數(shù)組的下標,累計相加的結(jié)果作為對應(yīng)數(shù)組的元素(即值)
b[$1]++:把第一列作為數(shù)組的下標,每出現(xiàn)一次計數(shù)器加1并且作為數(shù)組的元素(即值)
新聞名稱:awk命令用法及編程
URL分享:http://www.chinadenli.net/article36/gghssg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站收錄、云服務(wù)器、全網(wǎng)營銷推廣、服務(wù)器托管、手機網(wǎng)站建設(shè)、網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)