尚观linux笔记之awk与sed高级使用

发布时间:2020-07-30编辑:脚本学堂
本文内容主要是尚观学习笔记中awk与sed的高级应用实例,实现对非法IP的报警、封锁与解除封锁等。供大家参考。

代码如下:
 

复制代码 代码示例:

#!/bin/bash
LOGPATH="/home/andyguo"
LOGNAME="h_access.log"
#恢复被封闭ip时间单位是秒
TIME=50
#被封ip记录的log位置
FILENAME="/home/andyguo/msgreporter.log"
#过滤的内容
GR="GET /resume/showresumedetail"
#过滤内部特殊ip
gre_ip='27.115.103.179|58.246.147.*'
#---报警阀值设置#---##
typeset -i H #将其设置成数字类型便于比较大小
H=10#`date '+%H'`
echo  "当前时间"$H
#早上8点到下午16点为高峰时段
if([ $H -ge 8 -a $H -le 18 ])
then
   echo "高峰时段"
    N=1 #短信报警阀值
    FN=100 #封ip的阀值
    RN=1 #扫描简历报警阀值
#下午18点到23点为普通访问时段
elif([ $H -gt 18 -a $H -le 23 ])
then
  echo "普通访问时段"
    N=1 #短信报警阀值
    FN=1 #封ip的阀值
    RN=1 #扫描简历报警阀值
#其他时段
else
   echo "低谷时段"
   N=9 #短信报警阀值
   FN=1 #封iP的阀值
   RN=1 #扫描简历报警阀值
fi
echo "报警阀值" $N
echo "封ip阀值" $FN
echo "扫描简历阀值" $RN
#时间段截取
Y=`date '+%Y:'`
STARTTIME=$Y` date -d   ' minutes' |linuxjishu/13830.html target=_blank class=infotextkey>awk '{print $4}'`
ENDTIME=$Y`date -d ' -9 minutes'|awk '{print $4}'`
STARTTIME="2012:16:04:33"
ENDTIME="2012:16:00:33"
echo "开始时间:" $STARTTIME
echo "结束时间:"$ENDTIME

cd $LOGPATH

MSG="$LOGNAME: "
BOOL=0 #判断是否发短信

for ((i=1;i<=3;i++)) 
   do
msg=`cat $LOGNAME |awk -F / -v date1=$STARTTIME -v date2=$ENDTIME  '{if ($3>=date2 && $3<=date1) print}'|awk '{print $1}'|grep -v -|egrep -v $gre_ip |sort|uniq -c|sort -nr|sed -n ${i}p |awk -v n=$N '{if ($1>n) print "ip="$2"("$1")"}'`
        if [ -n "$msg" ];then
           BOOL=1
        fi
       MSG=$MSG$msg" "   
  done
echo "普通报警: " $MSG
echo "普通报警:"$MSG  >>/var/log/$LOGNAME

if [ $BOOL == 1 ];then
  for phone_num in   13810697234
  #for phone_num in 13810697234
  do
   echo "发短信"
    # wget -O /dev/null "http://127.0.0.1/sms/send?view_id=0&client_id=1004&data=[{%22tel%22:%22$phone_num%22,%22context%22:%22$SEND_MSG.[testcom]%22,%22kind%22:%2206%22}]"
   done
fi
#---
SEND_MSG="$LOGNAME "
SEND_BOOL=0
for ((i=1;i<=3;i++))
do
      send_msg=`cat $LOGNAME |grep "$GR"|awk -F / -v date1=$STARTTIME -v date2=$ENDTIME  '{if ($3>=date2 && $3<=date1) print}'|awk '{print $1}'|grep -v -|egrep -v $gre_ip|sort|uniq -c|sort -nr|sed -n ${i}p |awk -v n=$RN '{if ($1>n) print "ip="$2"("$1")"}'`
      if [ -n "$send_msg" ];then
          SEND_BOOL=1
       fi
      ip=`echo $send_msg |awk -F "(" '{print $1}'|awk -F "=" '{print $2}'`
      userid_nu=`cat $LOGNAME |awk -F / -v date1=$STARTTIME -v date2=$ENDTIME  '{if ($3>=date2 && $3<=date1) print}'|grep "$ip"|grep "$GR"|awk -F 't' '{print $11}'|grep -v "0"|sort|uniq -c|wc -l`
      SEND_MSG=$SEND_MSG$send_msg"(""$userid_nu"")"
done

echo "抓简历报警: "$SEND_MSG
echo "抓简历报警:"$SEND_MSG  >>/var/log/$LOGNAME
if [ $SEND_BOOL == 1 ];then
  for phone_num in   13810697234
  #for phone_num in 13810697234
  do
   echo "发短信"
   #   wget -O /dev/null "http://127.0.0.1/sms/send?view_id=0&client_id=1004&data=[{%22tel%22:%22$phone_num%22,%22context%22:%22$SEND_MSG.[testcom]%22,%22kind%22:%2206%22}]"
   done
fi

#---
#被封闭IP地址和时间记录的文件名称和地址

#现在时间
now=`date "+%Y-%m-%d %H:%M:%S"`
echo  "封ip的时间:" $now
iptables_MSG="$LOGNAME: "" unable visit ip "
IPTABLES_BOOL=0

for((i=1;i<=3;i++))
do
      iptables_msg=`cat $LOGNAME |awk -F / -v date1=$STARTTIME -v date2=$ENDTIME  '{if ($3>=date2 && $3<=date1) print}'|awk '{print $1}'|grep -v -|egrep -v $gre_ip|sort|uniq -c|sort -nr|sed -n ${i}p |awk -v n=$FN '{if ($1>n) print $2"("$1")"}'`
     if [ -n "$iptables_msg" ];then
          ip=`echo $iptables_msg|awk -F "(" '{print $1}'`
              IPTABLES_BOOL=1
              echo "封闭ip和时间"${ip}";"${now}
              echo ${ip}";"${now}>> $FILENAME
              echo "封闭IP:"$ip
              `/sbin/iptables -I INPUT -s ${ip} -p tcp --dport 80 -j DROP`
     fi

     IPTABLES_MSG=$IPTABLES_MSG$iptables_msg" "
done
echo $IPTABLES_MSG
echo $IPTABLES_MSG  >>/var/log/$LOGNAME
if [ $IPTABLES_BOOL == 1 ];then
  for phone_num in  13810697234
  #for phone_num in 13810697234
  do
    echo "发短信"
  #   wget -O /dev/null "http://127.0.0.1/sms/send?view_id=0&client_id=1004&data=[{%22tel%22:%22$phone_num%22,%22context%22:%22$SEND_MSG.[testcom]%22,%22kind%22:%2206%22}]"   done
fi

#---
#计算时间差
typeset -i result
#现在时间
now=`date "+%Y-%m-%d %H:%M:%S"`
echo  "解封ip时间:" $now
end=`date +%s -d "$now"
while read LINE
do
startime=`echo $LINE |awk  -F ";" '{print $2}'`
star=`date +%s -d "$startime"`
result=$(($end-$star))
if([ $result -ge $TIME ]);then
       ip=`echo $LINE |awk  -F ";" '{print $1}'`
            echo "封闭ip离现在已经"$result"秒"
            echo "清除ip"$ip
            `/sbin/iptables -D INPUT -s $ip -p tcp --dport 80 -j DROP`
             sed -i -e "/$LINE/d" $FILENAME
             echo $LINE
       fi
done < $FILENAME

附,grep和egrep的用法。
1,格式: grep [option] pattern filename 注意: pattern如果是表达式或者超过两个单词的, 需要用引号引用. 可以是单引号也可双引号, 区别是单引号无法引用变量而双引号可以.
 

复制代码 代码示例:
grep '<Tom>' file   包含单词Tom的行
grep 'Tom savage' file 包含Tom savage的行
grep '^Tommy' file 包含以Tommy开头的行
grep '.bak$' file 包含以.bak结束的行
grep '[Pp]yramid' file 包含pyramid 或Pyramid的单词的行
grep '[A-Z]' file 包含至少一个大写字母的行
grep '[0-9]' file 包含至少一个数字的行
grep '[A-Z]...[0-9]' file 包含五个字符,以大写开头, 和一个数字结尾的行.
grep -w '[tT]est' file 包含单词和test的行.
grep -s 'ken sun' file 找到包含ken sun的行, 但不打印行, 而是用来检查退出状态.
grep -v aaa file 打印不包含aaa的行.
grep -i cathy file 打印所有包含cathy的行, 而不考虑大小些.
grep -l 'dear cathy' * 打印包含dear cathy的文件的文件名清单.
grep -n tom file   打印匹配的行并追加行号.
grep "$LOGNAME" file 包含变量内容的行, 注意必须用双引号, 单引号则无法引用变量.
grep '$name' file 打印包含字符$name的行.

2,egrep = grep -E 可以使用基本的正则表达外, 还可以用扩展表达式. 注意区别.
扩展表达式:
 

复制代码 代码示例:

+ 匹配一个或者多个先前的字符, 至少一个先前字符.
? 匹配0个或者多个先前字符.
a|b|c 匹配a或b或c
() 字符组, 如: love(able|ers) 匹配loveable或lovers.
(..)(..)12 模板匹配. 1代表前面第一个模板, 2代第二个括弧里面的模板.
x{m,n} =x{m,n} x的字符数量在m到n个之间.

egrep '^+' file   以一个或者多个空格开头的行.
grep '^*' file   同上
egrep '(TOM|DAN) SAVAGE' file 包含 TOM SAVAGE 和DAN SAVAGE的行.
egrep '(ab)+' file 包含至少一个ab的行.
egrep 'x[0-9]?' file 包含x或者x后面跟着0个或者多个数字的行.
egrep 'fun.$' * 所有文件里面以fun.结尾的行.
egrep '[A-Z]+' file 至少包含一个大写字母的行.
egrep '[0-9]' file 至少一个数字的行.
egrep '[A-Z]...[0-9]' file 有五个字符, 第一个式大写, 最后一个是数字的行.
egrep '[tT]est' file 包含单词test或Test的行.
egrep 'ken sun' file 包含ken sun的行.
egrep -v 'marry' file 不包含marry的行.
egrep -i 'sam' file 不考虑sam的大小写,含有sam的行.
egrep -l "dear ken" * 包含dear ken的所有文件的清单.
egrep -n tom file 包含tom的行, 每行前面追加行号.
egrep -s "$name" file 找到变量名$name的, 不打印而是显示退出状态. 0表示找到. 1表示表达式没找到符合要求的, 2表示文件没找到。

3,fgrep 很简单就是固化表达式的搜索.如:
 

复制代码 代码示例:
fgrep "$name...[a-z]" file 就是在file里面找到和字符$name...[a-z]一样的行. 其中$和...等没有转义的意义。