|
##########################################################################################
部分题目引用自:https://www.centos.bz/2012/07/shell-script-exercises/
Q1题目:
分析图片服务日志,把日志(每个图片访问次数*图片大小的总和)排行,也就是计算每个url的总访问大小。本题生产环境应用:这个功能可以用于IDC网站流量带宽很高,然后通过分析服务器日志哪些元素占用流量过大,进而进行优化或裁剪该图片,压缩js等措施。
测试数据 access_log
59.33.26.105 – – [08/Dec/2010:15:43:56 +0800] “GET /static/images/photos/2.jpg HTTP/1.1″ 200 11299
输入要求:
本题需要输出三个指标: 【被访问次数】 【访问次数*单个被访问文件大小】 【文件名(带URL)】
Q1知识回顾:awk
awk 语法: [-F field-separator] '{pattern + action}' input-file(s)
awk 把文件逐行读入,默认域分隔符是"空白键" 或 "tab 键",可以用 -F ' ' 修改;$0则表示所有域,$1表示第一个域,$n表示第n个域。
常见例子:
awk -F: 'BEGIN {count=0;print "[start] user count is:",count} {count=count+1;print $1;} END {print "[end]user count is:" count}' /etc/passwd
[start]user count is 0
root
...
[end]user count is 40
!!重要技巧
因为awk是以字符串格式来存储数字值,但又可以进行数值计算;
并且数组中的下标也同样视为字符串array["1"]=array[1]。特别的,还可以用字符串来作为下标,myarr["name"]="Mr. Whipple",print myarr["name"] 正常。这种数组叫做关联数组。
Q1思路:
分析http日志,用awk命令
access_log中的第七列为访问的文件(路径),第十列为返回数据大小即图片大小B.
Q1解答:
#!/bin/bash
awk 'BEGIN{
}
{
url[$7]++;
size[$7]+=$10;
}
END{
for (item in url){
#访问次数大于10次打印出来
if(url[item] > 10){
print url[item],size[item]/1024 "K",item
}
}
}' /home/wwwlogs/access.log
url记录单个url被访问次数,size统计总字节。
##########################################################################################
Q2问题;
计算出1+2+3+..+100的结果。可以使用多种方法解答。
Q2知识回顾:
shell中的数学运算不同于$变量,
如:var=1+1 echo $var 输出的结果是1+1;
如:var=1 var=$var+1 echo $var 输出结果是1+1
数组运算不需要带$
整数运算:let,(()),$[],expr
浮点数运算:管道方法bc,awk,
for语法:for (()) do done
Q2解答1:
在有bc命令下:
#!/bin/bash
seq -s “+” 100 | bc
Q2解答2:
#!/bin/bash
sum=0
for ((i=0;i=a && t60){
print ip;
}
}
}'`
echo $badip
if [ ! -z $badip ];
then
for ip in $badip
do
if [ -z "`/sbin/iptables -nL |grep $ip`" ];
then
/sbin/iptables -I INPUT -s $ip -j DROP
fi
done
fi
##########################################################################################
Q4题目:
Name,Team,First Test, Second Test, Third Test
Tom,Red,5,17,22
Joe,Green,3,14,22
Maria,Blue,6,18,21
Fred,Blue,2,15,23
Carlos,Red,-1,15,24
Phuong,Green,7,19,21
Enrique,Green,3,16,20
Nancy,Red,9,12,24
计算每个人的平均成绩,每次测试的平均成绩和每组队的平均成绩。如果某次成绩为负数,则表示此人错过了测试,那计算平均成绩时排除此人再计算。输出的结果如下表,在名字的列表中,名字是10个宽度且左对齐(提示printf中使用%-10s格式),而平均值是7个字符宽度,右边两个右对齐的小数。
Name Average
---- -------
Tom 14.67
Joe 13.00
Maria 15.00
Fred 13.33
Carlos 19.50
Phuong 15.67
Enrique 13.00
Nancy 15.00
------------------
Average for Test 1 : 5
Average for Test 2 : 15.75
Average for Test 3 : 22.125
-------------------
Average for Red Team: 16
Average for Blue Team: 14.1667
Average for Green Team: 13.8889
Q4答案:
#!/bin/bash
awk -F "," 'BEGIN{
printf "%-10s %s\n","Name","Average";
printf "%-10s %s\n","----","-------";
}
NR>1{
for (i=3;i0){
name_count[$1]++;
name_sum[$1]+=$i;
test_count[i-2]++
test_sum[i-2]+=$i
team_count[$2]++;
team_sum[$2]+=$i;
}
}
printf "%-10s %7.2f\n",$1,name_sum[$1]/name_count[$1];
}
END{
print "------------------"
for (j=1;j |
|