Unix Shell範例精解---AWK練習(上)

Unix Shell範例精解第六章---AWK實用程序中有六個練習題,從簡單到複雜,目前做了前面3道題目,後面的3題感覺做起來很吃力,關於循環、數組、函數的題目,不知道要怎麼做。

AWK練習1:練習1主要練習的是模式爲正則表達式的操作,有些題目可以用書裏後面講解的內容解答

[kevin.tao@cws76 Ex_6.001-6.054]$ cat lab3.data 
Mike Harrington:(510) 548-1278:250:100:175
Christian Dobbins:(408) 538-2358:155:90:201
Susan Dalsass:(206) 654-6279:250:60:50 
Archie McNichol:(206) 548-1348:250:100:175 
Jody Savage:(206) 548-1278:15:188:150 
Guy Quigley:(916) 343-6410:250:100:175 
Dan Savage:(406) 298-7744:450:300:275 
Nancy McNeil:(206) 548-1278:250:80:75 
John Goldenrod:(916) 348-4278:250:100:175 
Chet Main:(510) 548-5258:50:95:135 
Tom Savage:(408) 926-3456:250:168:200 
Elizabeth Stachelin:(916) 440-1763:175:75:300 

該數據庫包含姓名、電話號碼、以及在最近3個月中的競選捐款數額

1.打印所有的電話號碼
awk -F '[: ]' '{print $3,$4 }' lab3.data      #設置字段分隔符爲冒號和空格

2.打印Dan的電話號碼
awk -F '[: ]' '/^Dan/{print $3 $4 }' lab3.data            #模式匹配Dan加上相應的動作

3.打印Susan的姓名和電話號碼
awk -F '[: ]' '/^Susan/{print $1,$2, $3 $4 }' lab3.data

4.打印所有姓以D開頭的姓氏
awk -F '[: ]' '$2~/^D/{print $2}' lab3.data                #$x ~ /xxx/這種方式很常用

5.打印所有以C或E開頭的名字
awk '/^[CE]/{print $1}' lab3.data

6.打印所有隻包含4個字符的名字
awk '/^....\>/{print $1}' lab3.data                 #這種雖然結果是對的,但是不嚴謹                                       
awk -F '[: ]' '$1~/^[a-zA-Z]{4}$/{print $1}' lab3.data      
awk -F '[: ]' '{if(length($1)==4){print $1}}' lab3.data      

7.打印所有區號爲916的人的名字
awk -F '[: ]' '$3=="(916)"{print $1}' lab3.data 
awk -F '[: ]' '$3~/916/{print $1}' lab3.data

8.打印Mike的資助金額,每一個值要使用美元符號開頭,例如“$250$100$175”
awk -F '[: ]' '/^Mike/{print "$"$5"$"$6"$"$7}' lab3.data 
awk -F '[: ]' '$1~/Mike$/{print "$"$5"$"$6"$"$7}' lab3.data

9.打印所有姓,後面跟着一個逗號和名
awk -F '[: ]' '{print $2","$1}' lab3.data

10.編寫一個名爲facts的腳本,並完成下面的工作:
a.打印所有姓氏爲Savage的人的全名和電話號碼
b.打印Chet的資助金額
c.打印所有在第一個月資助了250美元的人

腳本內容:
#/usr/bin/awk
#打印所有姓氏爲Savage的人的全名和電話號碼
$2~/Savage$/{print $1,$2,$3,$4}
#打印Chet的資助金額
$1~/Chet$/{print $5,$6,$7}
#打印所有第一個月資助250美元的人
$5~/250$/{print $1,$2}
#執行腳本時要改變FS的值

AWK 練習2 :主要練習模式爲比較表達式、關係運算符...等操作

[kevin.tao@cws76 Ex_6.055-6.089]$ cat lab4.data 
Mike Harrington:(510) 548-1278:250:100:175
Christian Dobbins:(408) 538-2358:155:90:201
Susan Dalsass:(206) 654-6279:250:60:50 
Archie McNichol:(206) 548-1348:250:100:175 
Jody Savage:(206) 548-1278:15:188:150 
Guy Quigley:(916) 343-6410:250:100:175 
Dan Savage:(406) 298-7744:450:300:275 
Nancy McNeil:(206) 548-1278:250:80:75 
John Goldenrod:(916) 348-4278:250:100:175 
Chet Main:(510) 548-5258:50:95:135 
Tom Savage:(408) 926-3456:250:168:200 
Elizabeth Stachelin:(916) 440-1763:175:75:300

該數據庫包含姓名、電話號碼、以及在最近3個月中的競選捐款數額

1.打印在第二個月捐款超過100美元的人的姓名和電話號碼
awk -F '[: ]' '$6>100{print $1,$2,$3 $4}' lab4.data

2.打印在最後一個月捐款少於85美元的人的姓名和電話號碼
awk -F '[: ]' '$7<85{print $1,$2,$3 $4}' lab4.data 

3.打印第一個月捐款額在75-150美元之間的人
awk -F '[: ]' '$5>75 && $5<150{print $1,$2}' lab4.data 

4.打印這三個月的捐款總額不超過800美元的人
awk -F '[: ]' '($5+$6+47)<800{print $1,$2}' lab4.data 
awk -F '[: ]' '{if(($5+$6+$7)<800){print $1,$2}}' lab4.data 

5.打印月均捐款額大於200美元的人的姓名和電話號碼
awk -F '[: ]' '($5+$6+$7)/3>200{print $1,$2,$3 $4}' lab4.data 
awk -F '[: ]' '{if(($5+$6+$7)/3>200){print $1,$2,$3 $4}}' lab4.data

6.打印不在916區的人的姓
awk -F '[: ]' '!($3=="(916)"){print $2}' lab4.data 

7.打印每條記錄,並在記錄前加上記錄號
awk '{print NR,$0}' lab4.data

8.打印每個人的姓名和捐款總額
awk -F '[: ]' '{print $1,$2,$5+$6+$7}' lab4.data

9.把Chet第二個月的捐款額加上10
awk -F '[: ]' '/^\<Chet\>/{print $6+10}' lab4.data 
awk -F '[: ]' '/^\<Chet\>/{$6=$6+10;print}' lab4.data 

10.把Nancy McNeil的名字改成Louise McInnes
awk -F '[: ]' '$1=="Nancy" && $2=="McNeil"{$1="Louise";$2="McInnes";print $1,$2 }' lab4.data

AWK練習3 :主要練習變量,格式控制、BEGIN END 等操作

[kevin.tao@cws76 Ex_6.090-6.126]$ cat lab5.data 
Mike Harrington:(510) 548-1278:250:100:175
Christian Dobbins:(408) 538-2358:155:90:201
Susan Dalsass:(206) 654-6279:250:60:50 
Archie McNichol:(206) 548-1348:250:100:175 
Jody Savage:(206) 548-1278:15:188:150 
Guy Quigley:(916) 343-6410:250:100:175 
Dan Savage:(406) 298-7744:450:300:275 
Nancy McNeil:(206) 548-1278:250:80:75 
John Goldenrod:(916) 348-4278:250:100:175 
Chet Main:(510) 548-5258:50:95:135 
Tom Savage:(408) 926-3456:250:168:200 
Elizabeth Stachelin:(916) 440-1763:175:75:300 

上面這個數據庫記錄內容包括姓名、電話號碼和最近3個月得競選捐款數額
試編寫一個能產生如下輸出的nawk腳本:

[kevin.tao@cws76 Ex_6.090-6.126]$ awk -f nawk.sc lab5.data 
       ***CAMPAIGN 1998 CONTRIBUTIONS***
--------------------------------------------------------------------------------------
NAME                   PHONE                Jan|     Feb |     Mar  |     Total Donated
--------------------------------------------------------------------------------------
Mike Harrington      (510) 548-1278    250.00  100.00  175.00   525.00
Christian Dobbins   (408) 538-2358    155.00   90.00  201.00   446.00
Susan Dalsass        (206) 654-6279    250.00   60.00   50.00   360.00
Archie McNichol      (206) 548-1348    250.00  100.00  175.00   525.00
Jody Savage            (206) 548-1278     15.00  188.00  150.00   353.00
Guy Quigley             (916) 343-6410    250.00  100.00  175.00   525.00
Dan Savage             (406) 298-7744    450.00  300.00  275.00  1025.00
Nancy McNeil          (206) 548-1278    250.00   80.00   75.00   405.00
John Goldenrod       (916) 348-4278    250.00  100.00  175.00   525.00
Chet Main                 (510) 548-5258     50.00   95.00  135.00   280.00
Tom Savage             (408) 926-3456    250.00  168.00  200.00   618.00
Elizabeth Stachelin  (916) 440-1763    175.00   75.00  300.00   550.00
----------------------------------------------------------------------------------
            SUMMARY
----------------------------------------------------------------------------------
The campaign received a total of 6137.00 for this quarter.           #所有人的捐款總和
The average donation for the 12 contribuors was $511.42.         #平均每人捐款多少
The highest contribution was $450.00.                                            #單月最大捐款 
The lowest contribution was $15.00.                                               #單月最低捐款

書本里面字段之間是對齊的,寫的腳本輸出的格式沒有很整齊,腳本內容如下:

[kevin.tao@cws76 Ex_6.090-6.126]$ cat nawk.sc 
#/usr/bin/awk
BEGIN { FS=":"
    printf "%40s\n","***CAMPAIGN 1998 CONTRIBUTIONS***"
    print "--------------------------------------------------------------------------------------"
    printf "%-22s %-16s %7s| %7s | %7s | %8s","NAME","PHONE", "Jan", "Feb","Mar","Total Donated\n"
    print "--------------------------------------------------------------------------------------"
    total=0;sum=0;lc=0;highest=0;lowest
}

{
total=$3+$4+$5;sum=sum+total;lc=lc+1
highest=(highest > $3)? highest : $3
highest=(highest > $4)? highest : $4
highest=(highest > $5)? highest : $5
lowest=(lowest==0 || lowest > $3)? $3 : lowest
lowest=(lowest < $4)? lowest : $4
lowest=(lowest < $5)? lowest : $5
printf "%-22s %-16s %7.2f %7.2f %7.2f %8.2f\n",$1,$2,$3,$4,$5,total
}

END {
    printf "----------------------------------------------------------------------------------\n"
    printf "\t\t\tSUMMARY\n"
    printf "----------------------------------------------------------------------------------\n"
    printf "The campaign received a total of %7.2f for this quarter.\n",sum
    printf "The average donation for the 12 contribuors was $%.2f.\n",sum/lc       #或者用sum/NR、sum/12
    printf "The highest contribution was $%.2f.\n",highest
    printf "The lowest contribution was $%.2f.\n",lowest
}
#total變量用於記錄每個人3個月捐款總數,sum變量用來記錄所有人的捐款總和,lc變量用來記錄記錄數目(sum/lc和sum/NR都等於sum/12 ),highest和lowest變量用來處理最大值和最小值。

總結:感覺awk學起來很困難,內容很多,書中後面的練習也做不出來,需要用到數組、函數、循環之類的功能,感覺awk腳本比bash腳本要難寫。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章