awk是可以对列进行操作,是很好用的文本处理器。
工作模式:
a、行处理模式,将行读取到awk内置变量$0中。
b、然后将这行的第一列读取到内置变量$1中,第二列读取到$2中,以此类推,直到这一行完成。(其中每列的分隔符默认是tab 或空格,分隔符会存储在内置变量FS中)
c、开始处理。
d、处理后进行打印输出。(输出时除了输出每列内容还有分隔符,OFS是输出分割符,默认是空格。)
e、下一行依旧$0 中。
awk的语法结构:
awk [选项] ‘/定址/{动作}’ 文件名
注意:这里的一定要是单引号‘’ 因为双引号是作为格式化输出的格式,包含在’'单引号里的,如果外边用双引号,就会报错。
选项常用的有
-F :指定分隔符
-f :指定awk脚本。
动作主要有:
print :标准输出
printf:格式化输出
定址:
正则表达式。
模式计算
等等
选项 -F
[root@www shell]# cat test-file3.txt
user1:x:2030:2030::/home/user1:/bin/bash
user2:x:2031:2031::/home/user2:/bin/bash
user3:x:2032:2032::/home/user3:/bin/bash
user4:x:2033:2033::/home/user4:/bin/bash
user5:x:2034:2034::/home/user5:/bin/bash
user6:x:2035:2035::/home/user6:/bin/bash
[root@www shell]# awk -F ":" -F ":" '{print $1 "\t" $3}' test-file3.txt
user1 2030
user2 2031
user3 2032
user4 2033
user5 2034
user6 2035
user7 2036
user8 2037
user9 2038
user10 2039
print :标准输出,这个后边的分割要加上“” 双引号,\t 是表示tab键。
-F,指定分隔符为:
可以用这个方式和windows的Excel 和CentOS系统做文件交换。
下边的输出可以直接复制出来,到Excel里正好是两列。
分隔符可以是多个
[root@www shell]# awk -F [:/] '{print $1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11}' test-file3.txt
user1 x 2030 2030 home user1 bin bash
user2 x 2031 2031 home user2 bin bash
user3 x 2032 2032 home user3 bin bash
user4 x 2033 2033 home user4 bin bash
多个分割符在 [这里面],遇到: 和 /就被识别长一列的。所以中间有很多空的列。
[root@www shell]# awk -F [:/] '{print $1"--"$2"--"$3"--"$4"--"$5"--"$6"--"$7"--"$8"--"$9"--"$10"--"$11}' test-file3.txt
user1--x--2030--2030------home--user1----bin--bash
user2--x--2031--2031------home--user2----bin--bash
user3--x--2032--2032------home--user3----bin--bash
user4--x--2033--2033------home--user4----bin--bash
换了一下输出分隔符OFS 就很明显了,两个–是一个列,可以看到 中间有好多空的列。
[root@www shell]# awk -F "" '{print $1}' test-file3.txt
u
u
u
指定分隔符为空。
print就是标准输出,刚刚一直在用,中间可以加不通的分隔符。
printf:格式化输出。
awk的格式化输出非常强。
主要有一下几个格式的设定:
%s : 输出字符串
%d : 输出整数(十进制)
%f : 输出浮点型数
有几点要注意的:
1、%s 输出的字符串包括字母、数字、符号等等,但是这里的数字不是真正的数字,而是识别成字符串了。
2、%d 取整是直接的取整,没有四舍五入,哪怕是10.99999,也会直接取成10。如果是字母和符号,会变为是0.
3、%f 浮点型的数,这种的默认保留小数点后6位,不够的补0,多的会四舍五入。同样的,字符串,符号,会变为0输出。
4、%s,这些是和$1这些对应的,一个% 对应一个 $,不过%可以比 $少,但不能多。%是控制输出的,可以计算出来,但是不输出,但是不能凭空输出。%<= $
5、默认不换行
测试用文件:
[root@www shell]# cat test-file4.txt
11.43 55.556667 name apple &^&%
1 2 3
80 10 90
67 3 70
[root@www 1108shell]# awk '{printf "%s,%s,%s,%s", $1,$2,$3,$4}' test-file4.txt
11.43,55.556667,name,apple1,2,3,80,10,90,67,3,70,[root@www 1108shell]# awk '{printf "%s,%s,%s,%s\n", $1,$2,$3,$4}' test-file4.txt
11.43,55.556667,name,apple
1,2,3,
80,10,90,
67,3,70,
%s后默认不换行,也就会出现上边的情况,换行就好了。
[root@www 1108shell]# awk '{printf "%s,%s--%s&&&%sooo%s\n", $1,$2,$3,$4,$5}' test-file4.txt
11.43,55.556667--name&&&appleooo&^&%
1,2--3&&&ooo
80,10--90&&&ooo
67,3--70&&&ooo
//中间的分隔符是可以随意指定的,并且可以看到,如果列不够么会直接输出分隔符,变为空列。
%d
[root@www shell]# awk '{printf "%d--%d--%d--%d--%d\n",$1,$2,$3,$4,$5}' test-file4.txt
11--55--0--0--0
1--2--3--0--0
80--10--90--0--0
直接取整,并且不是数的字符串变为0 输出,空列也是0.
%f
[root@www 1108shell]# awk '{printf "%f--%f--%f--%f--%f\n",$1,$2,$3,$4,$5}' test-file4.txt
11.430000--55.556667--0.000000--0.000000--0.000000
1.000000--2.000000--3.000000--0.000000--0.000000
//默认6位小数。
[root@www 1108shell]# awk '{printf "%.3f--%.3f--%.3f--%.3f--%.3f\n",$1,$2,$3,$4,$5}' test-file4.txt
11.430--55.557--0.000--0.000--0.000
1.000--2.000--3.000--0.000--0.000
//.3表示保留3位小数
[root@www 1108shell]# awk '{printf "%6.3f--%6.3f--%6.3f--%6.3f--%6.3f\n",$1,$2,$3,$4,$5}' test-file4.txt
11.430--55.557-- 0.000-- 0.000-- 0.000
1.000-- 2.000-- 3.000-- 0.000-- 0.000
//6 表示每个列占6个字符,这样可以令参差不齐的数据,看起来很整齐。
[root@www 1108shell]# awk '{printf "%-9.3f--%-9.3f--%9.3f--%9.3f--%9.3f\n",$1,$2,$3,$4,$5}' test-file4.txt
11.430 --55.557 -- 0.000-- 0.000-- 0.000
1.000 --2.000 -- 3.000-- 0.000-- 0.000
//9占9个字符,%-9.3f 这个%和f之间的-表示左对齐,这里默认是右对齐的
awk的格式化输出可以输出多行。甚至可以利用这一点,画一个表格。
[root@www 1108shell]# awk '{printf "|%-9.3f|%-9.3f|%9.3f|%9.3f|%9.3f|\n--------------------------------------------------\n",$1,$2,$3,$4,$5}' test-file4.txt
|11.430 |55.557 | 0.000| 0.000| 0.000|
--------------------------------------------------
|1.000 |2.000 | 3.000| 0.000| 0.000|
--------------------------------------------------
|80.000 |10.000 | 90.000| 0.000| 0.000|
--------------------------------------------------
|67.000 |3.000 | 70.000| 0.000| 0.000|
--------------------------------------------------
这里不是很好看,效果大概是这样的。
定址:
测试文件:
[root@www 1108shell]# cat test-file7.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:997:User for polkitd:/:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
g:x:1000:1000:g:/home/g:/bin/bash
squid:x:23:23::/var/spool/squid:/sbin/nologin
1、正则表达式
支持大部分正则表达式,但是\ ( \ ) 和 \ { \ }不支持。
[root@www 1108shell]# awk -F : '/^root/{print }' test-file7.txt
root:x:0:0:root:/root:/bin/bash
[root@www 1108shell]# awk -F : '/root/{print }' test-file7.txt
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
~ 匹配正则。
[root@www 1108shell]# awk -F: '$3 ~ /\<[0-9]\>/{print}' test-file7.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
//找到了所有第三列 匹配为数字,并且只有1个数字的,\<\>是分割单词的。表示只有1个数字的单词。
2、关系运算符:
== 等于
<= 小于等于
>= 大于等于
>!= 不等于
<小于
>大于
关系运算只作用于数值。
[root@www 1108shell]# awk -F: '$3 == 1 {print}' test-file7.txt
bin:x:1:1:bin:/bin:/sbin/nologin
//第三列等于 1的 也就是Uid等于1 的。
[root@www 1108shell]# awk -F: '$3 < 5{print}' test-file7.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
//第三列小于5的
[root@www 1108shell]# awk -F: '$2 < 5{print}' test-file7.txt
[root@www 1108shell]# awk -F: '$1 < 5{print}' test-file7.txt
[root@www 1108shell]#
//第一列小于5 的 但是第一列不是数字,不能计算,没有输出。
3、逻辑运算符
|| 或运算 两者只要有1个满足就可以
&& 与运算 两者都要满足
! 非运算 取反
[root@www 1108shell]# awk -F: '$3 >1 && $3 < 9{print}' test-file7.txt
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
// $3 >1 && $3 < 9 定址,第三列大于1 小于9的行
[root@www 1108shell]# awk -F: '$1 ~ /root/ || $1 ~ /bin/{print}' test-file7.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
// $1 ~ /root/ || $1 ~ /bin/ 第一列匹配root 或者第一类匹配bin的行
小结:~ 和!~ , 匹 配和不匹配,可以作用于字符串,也可以是数值型。
==、<=、>=、!=、<、>这些只能作用于数字。
不过~ 匹配,并不是精确的查找,只要包含就可以。
[root@www 1108shell]# awk -F: '$3 ~ /1/{print}' test-file7.txt
bin:x:1:1:bin:/bin:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
g:x:1000:1000:g:/home/g:/bin/bash
// $3 ~ /1/这些就是第三列有1 的行。
4、数值运算
+ 加
- 减
* 乘
/ 除
% 取余
^ 幂运算
测试文件。
[root@www 1108shell]# cat test-file4.txt
11.43 55.556667 name apple &^&%
1 2 3
80 10 90
67 3 70
[root@www 1108shell]# awk '{printf "%-5.1f %-5.1f %-5.1f %-5.1f %-5.1f\n",$1,$2,$3,$1+$2+$3,($1+$2+$3)/3}' test-file4.txt
11.4 55.6 0.0 67.0 22.3
1.0 2.0 3.0 6.0 2.0
80.0 10.0 90.0 180.0 60.0
67.0 3.0 70.0 140.0 46.7
// $1+$2+$3 求和 ($1+$2+$3)/3 均值
[root@www 1108shell]# awk '{printf "%-5.1f+%-5.1f+%-5.1f=%-5.1f %-5.1f\n",$1,$2,$3,$1+$2+$3,($1+$2+$3)/3}' test-file4.txt
11.4 +55.6 +0.0 =67.0 22.3
1.0 +2.0 +3.0 =6.0 2.0
80.0 +10.0 +90.0 =180.0 60.0
67.0 +3.0 +70.0 =140.0 46.7
//稍微改下分隔符。
AWK完整格式:
BEGIN{ 在文件处理之前执行的操作
打出表头
设置变量
设置分隔符等
只执行一次
}
/定址/{
定址:有定址则操作指定行。
没有定址操作所有行。
{}花括号里写的就是命令,也就是操作。
}
END{ 在文件执行后运行的操作
打印末尾
数据的汇总等等。
也是执行一次
}
[root@www 1108shell]# awk 'BEGIN{print "考试成绩汇总\n------------------" }{printf "%-5.1f %-5.1f %-5.1f %-5.1f %-5.1f\n",$1,$2,$3,$1+$2+$3,($1+$2+$3)/3}' test-file4.txt
考试成绩汇总
------------------
11.4 55.6 0.0 67.0 22.3
1.0 2.0 3.0 6.0 2.0
80.0 10.0 90.0 180.0 60.0
67.0 3.0 70.0 140.0 46.7
//这里就随便写了个表头。
AWK变量
1、内置变量
$0 :行
$1、$2… :列
FS:输入列分隔符
OFS:输出列分隔符
NR:行号
NF:列的数量。如果文件中,列的数量不一致。输出倒数第1列。
FS:FS== -F 选项在脚本中市用。
OFS:这个可以直接在脚本中指定OFS=“ ”这种的。
[root@www 1108shell]# awk '{print NR"、"$0}' test-file4.txt
1、11.43 55.556667 name apple &^&%
2、1 2 3
3、80 10 90
4、67 3 70
// $0 输出整行 NR是行号
[root@www 1108shell]# awk 'BEGIN{print "这个是表头";OFS="\t"} {print NR,$0}' test-file4.txt
这个是表头
1 11.43 55.556667 name apple &^&%
2 1 2 3
3 80 10 90
4 67 3 70
//这里$0 是变量 ,分隔符只有NR和$0之间有 $0 里的列 不适用BEGIN指定的输出分隔符。
[root@www 1108shell]# awk '{printf "%d,%s\n", NF,$NF}' test-file4.txt
5,&^&%
3,3
3,90
3,70
//打印列的数量和最后一列的内容。
[root@www 1108shell]# awk '{printf "%d,%s\n", NF,$(NF-1)}' test-file4.txt
5,apple
3,2
3,10
3,3
//打印列的数量和倒数第二列的内容,NF就是个数字,可以做加减等运算
2、自定义变量
变量=值
变量=数
变量=“字符串”
赋值运算:
a=5
a+=5 a=a+5
a-=5
[root@www 1108shell]# cat test-file4.txt
11.43 55.556667 name apple &^&%
1 2 3
80 10 90
67 3 70
[root@www 1108shell]# awk 'BEGIN{ sum=0;avg=0}{printf "%-9.3f %-9.3f\n" ,sum=$1+$2+$3, avg=sum/3}' test-file4.txt
66.987 22.329 //这个其实不算数,因为第三列是name 字符串直接是0
6.000 2.000
180.000 60.000
140.000 46.667
[root@www 1108shell]# awk '{a=a+1 ; print a}' test-file3.txt
1
2
3
4
5
6
7
8
9
10
[root@www 1108shell]# awk '{a=a+1}END{print a}' test-file3.txt
10
//test-file3.txt文件有10行所以之间的语句执行10次。每次加1 打印出来的就是1到10 。下边的END里打印一次,就是最终值10.
[root@www 1108shell]# awk '{a=a+1;print a}END{print a}' test-file3.txt
1
2
3
4
5
6
7
8
9
10
10
//这样看的就更清楚了正常打印一次,END又打印一次。2个10 。
AWK脚本。
随着命令的复杂程度提升,命令变得越来越长,不好查看修改。写到脚本中就比较容易看了,也能做更为复杂的操作。
[root@www shell]# cat gr.txt
me ULE ULA oracle
zhangyi 80 85 86
lier 78 76 90
wangsan 91 89 75
[root@www 1108shell]# awk -f gr.awk gr.txt
单科总成绩如下
249 250 251
[root@www 1108shell]# cat gr.awk
BEGIN{
ule=0
ula=0
oracle=0
print "单科总成绩如下"
}
NR>1{
ule=$2+ule
ula=$3+ula
oracle=$4+oracle
}
END{
print ule"\t"ula"\t"oracle
}
//-f 指定脚本。别的和正常的AWK命令一样
awk脚本的if
语法和C语言很像
if(判断条件)
{
动作
}
else if (判断条件)
{
动作
}
else
{
动作。
}
还是之前的文件,比如想确定ule的等级ABCDE分别为90 、80、70等等的人数。
[root@www 1108shell]# awk -f if-gr.awk gr.txt
人数统计
ule获得A的有1人。
ule获得A的有2人。
ule获得A的有2人。
ule获得A的有1人。
ule获得A的有1人。
[root@www 1108shell]# cat gr.txt
name ule ula oracle
zhangyi 80 85 86
lier 78 76 90
wangsan 91 89 75
zhaosi 65 77 57
liuwu 78 67 54
zhouliu 85 79 91
maqi 55 67 63
[root@www 1108shell]# cat if-gr.awk
BEGIN{
a=b=c=d=e=0
print "人数统计"
}
{
if ($2<100 && $2 >= 90)
{
a++
}
if ($2<90 && $2 >= 80)
{
b++
}
if ($2<80 && $2 >= 70)
{
c++
}
if ($2<70 && $2 >= 60)
{
d++
}
if ($2<60 )
{
e++
}
}
END{
print "ule获得A的有"a"人。"
print "ule获得A的有"b"人。"
print "ule获得A的有"c"人。"
print "ule获得A的有"d"人。"
print "ule获得A的有"e"人。"
}
awk的循环
语法:
for(变量初值;变量范围;变量更新)
{
动作
}
语法:
while (判断条件)
{
动作
变量更新
}
倒序输出行
[root@www 1108shell]# awk -f for-gr.awk test-file3.txt
/bin/bash:/home/user1::2030:2030:x:user1
/bin/bash:/home/user2::2031:2031:x:user2
/bin/bash:/home/user3::2032:2032:x:user3
/bin/bash:/home/user4::2033:2033:x:user4
/bin/bash:/home/user5::2034:2034:x:user5
/bin/bash:/home/user6::2035:2035:x:user6
/bin/bash:/home/user7::2036:2036:x:user7
/bin/bash:/home/user8::2037:2037:x:user8
/bin/bash:/home/user9::2038:2038:x:user9
/bin/bash:/home/user10::2039:2039:x:user10
[root@www 1108shell]# cat for-gr.awk
BEGIN{
FS=":"
}
{
i=NF
while (i>1)
{
printf "%s:" ,$i
i--
}
print $1
}
END{
}
awk 数组:
awk的数组
数组用于存储一组值。
数组里面的值(元素)用数组下标来表示。
数组名[下标]=元素
数组名 [ a-Z ] [ a - Z 0 - 9 _ ] *
下标 数字(正整数)
元素 “字符串” 数字
和shell中的数组一样,但是这个数组没有什么数组下标越界,只有能不能取到值这个说法。数组通常用于变量无法满足的时候,比如需要同事存储多个值。
BEGIN{
print "成绩统计"
ulesum=0
ulasum=0
oracle=0
ule_max=ula_max=oracle_max=0
}
NR>1{
name[NR]=$1
ulea[NR]=$2
ulaa[NR]=$3
oraclea[NR]=$4
# print $2+$3+$4
ulesum=ulesum+$2
ulasum=ulasum+$3
oracle=oracle+$4
#if ($2>ule_max)
#{
# ule_max=$2
# ule_max_name=$1
#}
}
END{
# print ulea[2]
print ulesum
print ulasum
print oracle
print "ule----avg:" ulesum/(NR-1)
print "ula----avg:" ulasum/(NR-1)
print "oracle----avg:" oracle/(NR-1)
printf "超过的有: "
for (i=1;i<NR+1;i++)
{
if (ulea[i]>ulesum/(NR-1))
{
#ulebigavg[k++]=name[i]
A++
printf "%s: " ,name[i]
}
}
printf "\n"
print "人数为"A
#for (j=0;j<+A;j++)
#{
#printf "%s: ", ulebigavg[j]
#}
#print "\n"
#"print "人数为"A
print "ula超过平均分的是:"
for (i=2;i<NR+1;i++)
{
if (ulaa[i]>ulasum/(NR-1))
{
B++
printf "%s: " , name[i]
}
}
printf "\n"
print "人数为"B
print "oracle超过平均分的是:"
for (i=2;i<NR+1;i++)
{
if (oraclea[i]>oracle/(NR-1))
{
C++
printf "%s: " , name[i]
}
}
printf "\n"
print "人数为"C
ulemax=ulea[2]
for (i=0;i<=NR;i++)
{
if (ulemax<ulea[i])
{
ulemax=ulea[i]
}
}
for (i=0;i<=NR;i++)
{
#print ulea[i]"---"name[i]
if (ulemax==ulea[i])
{
highname=name[i]
}
}
print "ule 分最高的是:" highname
print "ule 最高分为:"ulemax
}
awk常用的函数:
sub
gsub
替换
awk ‘{ sub ( / 定址 / , " 替换内容 " ) ; print }’ 文件名
[root@www 1111shell]# awk '{sub (/cat/, "CAT");print}' pet
dog CAT bird fish
CAT dog fish bird
CAT cat apple banana
hotdog fuck name sex
[root@www 1111shell]# awk '{sub (/cat/, "CAT",$2);print}' pet
dog CAT bird fish
cat dog fish bird
cat CAT apple banana
hotdog fuck name sex
//上边的是替换每行第个匹配项。下边的是第二列的匹配项。
[root@www 1111shell]# awk 'gsub (/cat/,"CAT")' pet
dog CAT bird fish
CAT dog fish bird
CAT CAT apple banana
//gsub,替换全部
toupper() 小写转大写
tolower() 大写转小写
转1 和 3 列。
[root@www 1111shell]# awk '{print toupper($1)" " toupper($3)}' pet
DOG BIRD
CAT FISH
CAT APPLE
HOTDOG NAME
转整行。
[root@www 1111shell]# awk '{print toupper($0)}' pet
DOG CAT BIRD FISH
CAT DOG FISH BIRD
CAT CAT APPLE BANANA
HOTDOG FUCK NAME SEX
awk练习
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个月的竞选捐款数额。
请编写一个能产生如下输出的awk脚本:
***FIRST QUARTERLY REPORT***
***CAMPAIGN 2004 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 总额 of $6137.00 for this quarter.
The 平均 donation for the 12 contributors was $511.42.
The 最高 total contribution was $1025.00 made by Dan Savage.
***THANKS Dan***
The following people donated 超过 $500 to the campaign.
They are eligible for the quarterly drawing!!
Listed are their names (sorted by last names) and phone numbers:
John Goldenrod--(916) 348-4278
Mike Harrington--(510) 548-1278
Archie McNichol--(206) 548-1348
Guy Quigley--(916) 343-6410
Dan Savage--(406) 298-7744
Tom Savage--(408) 926-3456
Elizabeth Stachelin--(916) 440-1763
Thanks to all of you for your continued support!!
[root@www 1111shell]# awk -f juankuan2.awk juankuan.txt
-------------------------------------------------------------------------------
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
------------------------------------------------------------------------------
捐款总额为 6137 。
12个月的捐款平均值为 511.417 。
捐款总数最多的是 Dan Savage 金额为 1025.00 元。
**** THANKS Dan Savage****
超过500的人:
Mike Harrington --- (510) 548-1278
Archie McNichol --- (206) 548-1348
Guy Quigley --- (916) 343-6410
Dan Savage --- (406) 298-7744
John Goldenrod --- (916) 348-4278
Tom Savage --- (408) 926-3456
Elizabeth Stachelin --- (916) 440-1763
Thanks to all of you for your continued support!!
[root@www 1111shell]# cat juankuan2.awk
BEGIN{
FS=":"
print "-------------------------------------------------------------------------------"
print " NAME PHONE Jan | Feb | Mar | Total Donated"
print "--------------------------------------------------------------------------------"
sum_total=0
max_m_money=0
max_m_name=""
i=0
j=0
}
{
printf "%-20s %14s %8.2f %8.2f %10.2f %8.2f\n" ,$1,$2,$3,$4,$5,$3+$4+$5
sum_total=sum_total+($3+$4+$5)
total_donated=$3+$4+$5;
if( total_donated > max_m_money){
max_m_money=total_donated;
max_m_name=$1;
}
if (total_donated >= 500){
big_than_five_name[i++]=$1
big_than_five_phone[j++]=$2
}
}
END{
print "------------------------------------------------------------------------------"
print " SUMMARY"
print "------------------------------------------------------------------------------"
print "捐款总额为 "sum_total" 。"
print "12个月的捐款平均值为 "sum_total/12" 。"
printf "捐款总数最多的是 %s 金额为 %.2f 元。\n",max_m_name,max_m_money
print " **** THANKS "max_m_name "****"
print "超过500的人:"
for (k=0;k<i;k++){
print " "big_than_five_name[k]" --- "big_than_five_phone[k]
}
print "Thanks to all of you for your continued support!!"
}