- 论坛徽章:
- 0
|
本帖最后由 helpid 于 2013-07-03 14:58 编辑
第一题: 使用awk可以快速的统计出TOP10的IP地址以及数量
方法1:- awk '{a[$NF]++}END{for(i in a)print i,a[i]}' illegal.log | sort -k2nr | head
复制代码 方法2:- awk '{a[b[$NF]++]}END{for(i=asort(a);i>0;i--)for(j in b)if(b[j]==i)print j" - "b[j]}' illegal.log | head
复制代码 第二题: 个人分析:
这个问题关键在于时间点的控制,通过观察日志,
我发现并不是每一秒或每一分钟都有日志产生的。所以
有可能在日志记录过程中,某个时间点或时间段就没有信息写入日志文件
那么:
A. 如果当前时间之前的10分钟这个时间点在日志中存在,
则设定查找内容范围从这个时间点开始直到日志文件末尾。
B. 如果当前时间之前的10分钟这个时间点日志中不存在
则查找距离这个时间点最近的一个时间,并且这个时间点必须为当前时间之前的10分钟以内的时间点
查找内容内容页从这个时间点开始直到日志文件末尾
最后通过使用sed语句来筛选出10分钟以内的日志内容,并进行关键字搜寻
如果在这段日志内容中包含有<Error>关键字就读取出来写入文件再发送邮件
否则就正常退出
B情况暂时没想出来如何实现....
A情况的处理方法:
第一步:编写脚本文件保存为 log_check.sh
# ========================================
- #!/bin/bash
- # log_check.sh
- stm="`date -d '-10 minutes'`"
- tag="<Error>"
- file="`mktemp`"
- sed -n "/${stm}/,/$/{/${tag}/p}" wls_ms1.out > ${file}
- [ -e ${file} ] && mail -s "Error" admin@ChinaUnix.net < ${file}
- rm -f ${file}
复制代码 # =================END====================
第二步:编写计划任务
在当前用户下执行crontab -e添加计划任务:- */10 * * * * /bin/bash log_check.sh
复制代码 第三题:我的思路是通过for循环来跑指定的IP段把所有不需要备份的目录及文件统一写到一个文件中,在执行tar打包时通过 -X参数来排除
- #!/bin/bash
- # Everyday 00:00:00 Run backup script.
- # 0 0 * * * /bin/bash /var/ChinaUnix/AppServerBackup.sh
- TODAY=`date +%Y%m%d`
- WEEKDAY=`date +%w`
- REMOTE_NETMASK=192.168.1 # 子网段
- REMOTE_IPS=(3 100) # 子网IP
- REMOTE_BACKUP_PATH=/opt/WebSphere/AppServer/profiles/
- LOCAL_SAVE_PATH=/var/ChinaUnix/
- EXCLUDE_PATH=(bin logs)
- EXCLUDE_FILE=(*.log *heapdump* *.gz *.tar *.zip *.bak)
- EXCLUDE_FILENAME=exclude.file
- function PrintLogs()
- {
- echo -e "<$(date +'%F %T')> $*"
- }
- function setBackupParts()
- {
- case ${WEEKDAY} in
- 0) args='-cjvpPf';; # Full Backup
- [1-6]) args='-ujvpPf';; # Update Backup
- esac
- }
- function setExcludeValue()
- {
- if [ ! -e ${EXCLUDE_FILENAME} ]
- then
- echo "${EXCLUDE_PATH[@]} ${EXCLUDE_FILE[@]}" | xargs -n1 > ${EXCLUDE_FILENAME}
- fi
- }
- function printResult
- {
- PrintLogs "==================================="
- PrintLogs "Bacup Success IP Total: ${SUCCESS}"
- PrintLogs "Bacup Failure IP Total: ${FAILURE}"
- if [ ${FAILURE} -gt 0 ]
- then
- for i in ${FAILURE_IPS}
- do
- PrintLogs "${i}"
- done
- fi
- echo "==================================="
- }
- function backupFile()
- {
- echo "Start Backup."
- # 设置备份参数
- setBackupParts
- # 设置排除文件
- setExcludeValue
-
- for((i=${REMOTE_IPS[0]};i<=${REMOTE_IPS[1]};i++))
- do
- ip=${REMOTE_NETMASK}.${i}
- file=${TODAY}_${ip}.tar.bz2
- ssh ${ip} "test -f ${EXCLUDE_FILENAME}" &>/dev/null
- [ $? -ne 0 ] && scp ${EXCLUDE_FILENAME} ${ip} &>/dev/null
-
- ssh ${ip} "test -d ${REMOTE_BACKUP_PATH}" &>/dev/null
- if [ $? -eq 0 ]
- then
- ssh ${ip} "tar ${args} -X ${EXCLUDE_FILENAME} ${file} ${REMOTE_BACKUP_PATH}" &>/dev/null
- scp ${ip}:${file} ${local_save_path} &>/dev/null
- ssh ${ip} "rm -f ${file}" &>/dev/null
- PrintLogs "${ip} done"
- ((SUCCESS++))
- else
- FAILURE_IPS="${ip} ${FAILURE_IPS} "
- ((FAILURE++))
- continue
- fi
- done
- PrintLogs "Backup End."
-
- # 输出备份结果
- printResult
- }
- SUCCESS=0 # 操作成功计数器
- FAILURE=0 # 操作失败计数器
- FAILURE_IPS=""
- USED_TIME=0 # 流程耗时计算器
- # 执行文件备份
- backupFile
复制代码 在当前用户下执行crontab -e添加计划任务:- 0 0 * * * /bin/bash /var/ChinaUnix/AppServerBackup.sh
复制代码 第四题 答:
&& || 是控制操作符,分别代表AND和OR
command2 只有在 command1 返回 0 时才被执行。
command3 只有在 command1 返回非 0 时才被执行。
AND 和 OR 序列的返回状态是序列中最后执行的命令的返回状态。
if then else fi 结构是多路分支条件测试语句, 用来判断命令列表的退出状态码是否为0(0表示"成功", 如果成
功的话, 那么就执行接下来command2命令.如果不成功(退出状态码为非0),就执行else的command3
两者相比,使用控制操作符进行条件测试更为简洁,比较适合于简单的测试语句
if then else fi 结构则具有更好的扩展性能。
第五题:答:
方法1:- echo 1234 | awk '{n=length;s=0;for(i=1;i<=n;i++){s+=substr($0,i,1)}print s}'
复制代码 方法2:- a=1234 && for((i=0;i<${#a};i++));do ((s+=${a:$i:1}));done; echo ${s}
复制代码 第六题:答:
1. 首选在计算之前需要判断给的日期是否有效
如果输入的日期无效或格式不正确则应该提示错误。
如果输入的日期是有效日期则算出是这年的第几天。
# ========================= Start =========================
- #!/bin/bash
- # Exp: sh caldate.sh 2013-05-23
- NormalYear_YearRex='([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]|[0-9][1-9][0-9]{2}|[1-9][0-9]{3})'
- NormalYear_MonthDayRex='((0[13578]|1[02])[-/](0[1-9]|[12][0-9]|3[01])|(0[469]|11)[-/](0[1-9]|[12][0-9]|30)|02[-/](0[1-9]|1[0-9]|2[0-8]))'
- LeapYear_YearRex='(([0-9]{2})(0[48]|[2468][048]|[13579][26])|(0[48]|[2468][048]|[3579][26])00)'
- LeepYear_MonthDayRex='(02[-/]29)'
- DateRex="^(${NormalYear_YearRex}[-/]${NormalYear_MonthDayRex}|${LeapYear_YearRex}[-/]${LeepYear_MonthDayRex})$"
- function calDateDays()
- {
- echo "$*" | awk -F'[-/]' -v Rex="${DateRex}" --re-interval '
- {
- if($0~Rex)
- {
- tstamp=mktime($1" "$2" "$3" 00 00 00");
- print strftime("%j",tstamp);
- }
- else
- {
- print "invalid date: "$0;
- }
- }' | sed 's/^0//'
- }
- dt="$*"
- calDateDays ${dt}
复制代码 # ========================= END =========================
2. 首选在计算之前需要判断给的日期是否有效
如果输入的日期无效或格式不正确则应该提示错误。
如果输入的日期是有效日期则算出是这年的第几天。
时间偏移值可以是 [+-]Nday.
+ 代表未来的时间 - 代表之前的时间
N 为任意整数均可
# ========================= Start =========================
- #!/bin/bash
- # Exp: sh caldate.sh 2013-03-01 -1day
- YearRex='([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]|[0-9][1-9][0-9]{2}|[1-9][0-9]{3})'
- MonthDayRex='((0[13578]|1[02])[-/](0[1-9]|[12][0-9]|3[01])|(0[469]|11)[-/](0[1-9]|[12][0-9]|30)|02[-/](0[1-9]|1[0-9]|2[0-8]))'
- LeapYearRex='(([0-9]{2})(0[48]|[2468][048]|[13579][26])|(0[48]|[2468][048]|[3579][26])00)'
- LeepMonthDayRex='(02[-/]29)'
- DateRex="^(${YearRex}[-/]${MonthDayRex}|${LeapYearRex}[-/]${LeepMonthDayRex})$"
- function calDate()
- {
- case "$2" in
- yesterday) setDays='-1';;
- tomorrow) setDays='+1';;
- [+-][0-9]*day) setDays=${2/day/};;
- *) echo "Offset Days Input Error!"
- exit 1;;
- esac
- echo "$1" | awk -F'[-/]' -v Rex="${DateRex}" -v offset="${setDays}" --re-interval '
- {
- if($0~Rex)
- {
- OFS=substr($0,5,1);
- tstamp=mktime($1" "$2" "$3+offset" 00 00 00");
- yyyy=strftime("%Y",tstamp);
- mm=strftime("%m",tstamp);
- dd=strftime("%d",tstamp);
- print yyyy,mm,dd;
- }
- else
- {
- print "invalid date: "$0
- }
- }'
- }
- dt="$1"
- offset="$2"
- calDate ${dt} ${offset}
复制代码 # ========================= END =========================
第七题:答:
九宫格排列如下:
8 6 9
4 2 5
7 3 1
8,2,1的位置固定不变;6与4、9与7、5与3 的位置可互换
解题思路:
1. 题目要求六个三位数都必须是奇数, 相加总和是 4446
1-9当中, 奇数为 1 3 5 7 9 总和是25
偶数为 2 4 6 8 总和是20
2. 由于总数4446的个位是6,且六个三位数都是奇数,而1-9当中只有5个奇数。总和为25(个位为5)
要是总数的个位为6,则只有 5 + 1 = 6
这样 第三行第三列就必定为1
由于个位数全为奇数,故九宫格中除了第一行第一列、第一行第二列、第二行第一列、第二行第二列
这四个交叉位 为偶数外,其余的 第一行第三列、第二行第三列 第三行第一列、第三行第二列、第三行第三列
这五个交叉位都为奇数。除去第三行第三列已确定为1外。剩下的第一行第三列、第二行第三列 第三行第一列、第三行第二列
有可能为3 5 7 9,
3. 通过分析总数4446是一个较大数。按照百位优先大数字的原则,我们把9与7放在百位。这样就会有1个900、1个700以上的数字
4. 由于在九宫格中存在3个交叉位的数数字会出现2次。偶数中有可能会是 2,4,6,8
而2468 中8最大。故8应该放在 会出现2次的交叉位上,且为百位。那么 第一行第一列就非8莫属,这样就会有2个 800以上的数字
而最小的偶数则放置在九方格最中间位置。
5. 最后进行计算。只要8,2,1的位置固定不变,6与4、9与7、5与3 的位置进行互换得出的总数均为4446.
第八题: 答:可以刪除!
bash中使用IFS(Internal Field Separator)这个变量用作shell指定的缺省域分隔符
原理上来说域分隔符可以为任意字符,但通常默认情况下IFS=" \n\t",即空格、新行、或tab键
rm指令中使用的"*"在這裡是作為一個通配符來使用,可以匹配包含空格的文件
所以"rm *"指令時可以刪除文件名包含空格的文件的。
第九题:不是很清楚,求指教!
第十题:
1. 列出当前目录下的非 20130605开头的文件2.
- #!/bin/bash
- # Exp sh prodiff.sh
- # 2. 将文件名中所有的空格, []去掉。
- for a in dirA/* dirB/*;do b="${a//[] []/}";[ "${a}" != "${b}" ] && mv "${a}" "${b}";done
- filesA=(`ls dirA | grep -E '.(che|XQF)`)
- for fileA in ${filesA[@]}
- do
- filesB=(`ls dirB | grep -E '.(che|XQF)`)
- for fileB in ${filesB[@]}
- do
- if [ "${fileA}" == "${fileB}" ]
- then
- # 3. 删除 dirA 下与 dirB 下重复的.che或.XQF文件
- rm -f dirA/${fileA} dirB/${fileB}
- else
- # 4. 删除.XQF对应的.che文件
- if [ ".${fileA##*.}" == ".XQF" ]
- then
- a1=`echo ${filesA[@]}| xargs -n1 | grep ${fileA%%.*}.che`
- [ -n "${a1}" ] && rm -f dirA/${a1}
- b1=`echo ${filesB[@]}| xargs -n1 | grep ${fileA%%.*}.che`
- [ -n "${b1}" ] && rm -f dirB/${b1}
- fi
-
- if [ "$.{fileB##*.}" == ".XQF" ]
- then
- b2=`echo ${filesB[@]}| xargs -n1 | grep ${fileB%%.*}.che`
- [ -n "${b2}" ] && rm -f dirB/${b2}
- a2=`echo ${filesA[@]}| xargs -n1 | grep ${fileB%%.*}.che`
- [ -n "${a2}" ] && rm -f dirA/${a2}
- fi
- fi
- done
- done
复制代码 |
|