第二十四章 shell中色彩处理和AWK 使用技巧

 本节所讲内容

24.1  shell中的色彩处理

24.2  AWK基本应用

24.3   AWK 高级应用

24.4   实战-shell脚本实战

24.1   Shell中的色彩处理

shell脚本显示内容带颜色显示,echo  显示带颜色,需要使用参数-e

格式1  : echo -e  "\033[背景颜色;文字颜色m  要输出的字符 \033[0m"

格式2  : echo -e   "\e[背景颜色;文件颜色m要输出的字符\e[033"

例1  绿底蓝字


去掉绿底




发现后期是输出闪烁状态,  使用0m  来关闭所有属性

常见颜色字体



3x  代表字体  ,4x   代表背景颜色

24.2  awk  基本应用

grep   和egrep   :  文本过滤的

sed  :  流编译器,实现编译的

awk  :  文本报告生成器  实现格式化文本输出


awk  ------->  gawk  :  gun  awk  

在linux 常见gawk  awk  是gawk  的连接文件


模式:

正则表达式 :/root/匹配含有root的行,   /*.root/

关系表达式:  <   >   &&   || + *    

匹配表达式 :    ~  !    ~   

变量  命令  内置函数    流程控制语句

它的语法结构如下

awk  [options] 'BEGIN{print 'start'}  'pattern{commands}' END {print 'end'}'   file

其中: BEGIN   END是awk 的关键字部,因此必须大写,着两个部分喀什块和结束块是可选的




                                        开始执行END模块的命令 

通过上面我们可以知道:  awk  它工作通过三个步骤

1  读:  从文件,管道或者标准输入中读入一行然后把它存放到内存中

2  执行   :  对每一行数据   根据awk  命令按顺序执行,默认情况下是处理每一行数据,也可以指定模式

3  重复:  一直重复上述两个过程直到文件结束

awk支持两种不同类型的变量,内置变量,自定义变量

awk 内置变量 (预定义变量)

$n   当前记录的第n个字段,比如  n为1   表示第一个字段,n 为2  表示第二个字段

$0    这个变量包含执行过程中当前的文本内容

FILENAME   当前输入文件的名

FS   字段分隔符  (默认是任何空格)

NF表示字段数,在执行过程中对应于当前的字段数,NF  :  列的个数  

FNS     个文件分别计数的行号

NR 表示记录数,在执行过程中对应当前的行号

OFS   输出字段分隔符 (默认值是一个空格)

ORS  输出记录分隔符(默认值是一个换行符)

RS  记录分隔符  (默认是一个换行符)


24.2.2   实例演示

常用的命令选项

-F  fs  指定分隔符

-v  赋值衣蛾用户自定义变量

-f   指定脚本文件,从脚本中读取awk  命令

(1)   分隔符的使用

用法 :-F   fs   其中fs  是指定分隔符,fs  可以是字符串或政策表达式,分割符是默认是空格

常见写法:  -F  :  -f ,  -F   [Aa]

例1  

打开   /etc/passwd 

例2   

例外一种写法  使用FS  指定分隔符

[root@localhost ~]# echo "12AxAbADXaAD52" | awk 'BEGIN {FS="aA"} {print $2} '

D52

[root@localhost ~]#

例4  过滤出本系统中的IP地址


[root@localhost ~]# ifconfig ens33 | grep netmask

        inet 192.168.24.169  netmask 255.255.255.0  broadcast 192.168.24.255

[root@localhost ~]# ifconfig ens33 | grep netmask  | awk '{print $2}'

192.168.24.169

()

(2)  关系运算符的使用

[root@localhost ~]# echo "3 2 3 4 5" > a.txt

[root@localhost ~]# awk '{print $1+10}' a.txt

13



取出第四个   第一种方法


[root@localhost ~]# echo "one two three four" | awk '{print $NF}'     NF   代表最后一个  

four

[root@localhost ~]# echo "one two three four" | awk '{print $(NF-2)}'  打印到处第三列

two

[root@localhost ~]#

[root@localhost ~]# echo "one two three four" | awk '{print $(NF/2-1)}'

one

例2   打印出passwd  文件中小于10   的用户名  和它登录使用的shell

参数 :$NF    最后一行

[root@localhost ~]# awk -F: '$3<10{print $1 $NF}' /etc/passwd   #  直接输出格式太乱

root/bin/bash

bin/sbin/nologin

daemon/sbin/nologin

adm/sbin/nologin

lp/sbin/nologin

sync/bin/sync

shutdown/sbin/shutdown

halt/sbin/halt

mail/sbin/nologin

第二种方法

#  awk  格式化输出

注意   在最外面使用单引号   ''   里面使用双引号   ""

[root@localhost ~]# awk -F: '$3<10{print $1 "\t" $NF}' /etc/passwd   #  \t  作为分隔符

[root@localhost ~]# awk -F: '$3<10{print $1 ,$NF}' /etc/passwd  

例3     打印出passwd  文件中大于1000   的用户名  和它登录使用的shell为bash

[root@localhost ~]# awk -F: '$3>=1000 && $NF=="/bin/bash" {print $1 "\t" $NF}' /etc/passwd

centos /bin/bash


例3    添加开始和结束模块  

1)[root@localhost ~]# vim test.awk

2)BEGIN{

        print "UserID\t\t\tShell"

        print "---------------------------"

        FS=":"

}

$3>=500 && $NF=="/sbin/nologin"{

        printf "%-20s %-20s\n",$1,$NF

}

END {

    print "---------------------------"

}

~

3)[root@localhost ~]# awk -f test.awk /etc/passwd

UserID Shell

---------------------------

polkitd              /sbin/nologin     

libstoragemgmt      /sbin/nologin     

colord              /sbin/nologin     

gluster              /sbin/nologin

左对齐  : "-"   "%-20s"   |    ;    右对齐    “+”  " %+20s" 

(3)  在脚本中的一些应用


1)[root@localhost ~]# vim aa.sh

2)#! /bin/bash

echo "当前系统内存使用百分比:"

USEFREE=`free -m | egrep Mem | awk '{print $3/$2*100"100%"}'`

echo -e "内存使用百分比:  \e[31m${USEFREE} \e[0m" 

~                                                 


3)[root@localhost ~]# bash aa.sh

当前系统内存使用百分比:

内存使用百分比:  45.7394100%

24.3    awk 高级应用    

命令格式

awk   [-F |-f | -v]   ‘BEGIN{} // {command1;command2}  END{}’  file  

-F   指定分隔符   

-f   调用脚本

-v    定义变量

‘{}’   引用代码块

{.....}  命令代码块,包含一条或多条命令

  BEGIN   初始化代码块

/str/    匹配代码块  。可以是字符串或者正则表达式 

{print  A,printB }   多条命令使用分号分割

END   结尾代码块

在awk中,pattern   有以下几种

1)  empty   空模式,这个也是我们常用的

2)  /regular/  expression  /   仅处理能够被这个模式匹配的行

3)   例  :  打印root开头的行

[root@localhost ~]# awk -F: '/^root/{print $0}' /etc/passwd

root:x:0:0:root:/root:/bin/bash

3 )  行范围匹配,startline,endline  

例1  :输出行号大于等3 而且小于等于6 的行

[root@localhost ~]# awk -F: '(NR>=3&&NR<=6){print NR, $0}' /etc/passwd

3 daemon:x:2:2:daemon:/sbin:/sbin/nologin

4 adm:x:3:4:adm:/var/adm:/sbin/nologin

5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

6 sync:x:5:0:sync:/sbin:/bin/sync


打印本机的IP地址 

例1   使用NR  行号来定位,然后提取IP地址

注意:这个思路很多好,之前都是通过,过滤关键字来定位,这次是通过行号,多了一个思路

[root@localhost ~]# ifconfig ens33 | awk -F " " 'NR==2{print $2}'

192.168.24.171


NR   和FNR  的区别


有三种去掉首行的方法

[root@localhost ~]# route -n | grep -v ^Kernel

Destination    Gateway        Genmask        Flags Metric Ref    Use Iface

0.0.0.0        192.168.24.2    0.0.0.0        UG    100    0        0 ens33

192.168.24.0    0.0.0.0        255.255.255.0  U    100    0        0 ens33

192.168.122.0  0.0.0.0        255.255.255.0  U    0      0        0 virbr0



第二种方法  使用sed  

[root@localhost ~]# route -n | sed 1d

Destination    Gateway        Genmask        Flags Metric Ref    Use Iface

0.0.0.0        192.168.24.2    0.0.0.0        UG    100    0        0 ens33

192.168.24.0    0.0.0.0        255.255.255.0  U    100    0        0 ens33

192.168.122.0  0.0.0.0        255.255.255.0  U    0      0        0 virbr0

第三种方法  使用awk 


例4  使用awk  查出包括root字符的行,有以下3种方法


不匹配root

[root@localhost ~]# awk -F: '!/root/{print $0}' /etc/passwd


以bash  结尾的

[root@localhost ~]# awk -F: '!/bash$/{print $0}' /etc/passwd


用if(条件){命令1; 命令2}  elif  (条件){命令;} else  {命令} 中,在比较条件中()  括起来,在awk中,如果条件为真,0  为假

例:  如果UID大于10  ,则输出user=>  用户名,否则输出pass=> 用户名

[root@localhost ~]# awk -F: '{if($3<10){print "user=>"$1}else{print "pass="$1}}' /etc/passwd

user=>root

user=>bin

user=>daemon

user=>adm

user=>lp

user=>sync

user=>shutdown

~  匹配

!~   不匹配

例5: 查出行号小于等于5并且bin/bash   的行

[root@localhost ~]# awk -F: '{if($3<=5 && $NF ~"bin/bash"){print $1,$NF}}' /etc/passwd

root /bin/bash

例6   变量

1)   用-v  指定  var=value   变量名区分大小写

2)   在程序中直接定义

3)   在awk里,使用变量不加$  符号

[root@localhost ~]# var="test"

[root@localhost ~]# awk 'BEGIN{print "'$var'"}'   #  引用变量时,使用单引号,把引号括起来


test

例7  :格式化输出

printf   命令  :格式化输出,printf    "FORMAT"  ,item1,item2 

format  使用注意事项

1  其与print  命令最大的不同时,printf  需要指定format 样式

2   format  用于指定后面的每个item 的输出格式

3    printf  语句不败打印item 的输出格式

4   format  格式的指示符都以%  开头,后面跟一个字符,如下

%c  :   显示字符的ASCII码 

%d  ,%i  :  十进制整数

%e,%E  :  科学计数法显示数值

%f  :  显示浮点数

%g  ,%G  以科学计数法的格式或浮点数的格式显示数值

%s   显示字符串

%u  无符号整数

%%  显示%  自身



[root@localhost ~]# awk -F: '{printf "%s",$1}' /etc/passwd

rootbindaemonadmlpsyncshutdownhaltmailoperatorgamesftpnobodysystemd-networkdbuspolkitdlibstoragemgmtcolordrpcglustersaslauthabrtrtkitpulseradvdrpcusernfsnobodyunboundchronyqemutssusbmuxdgeocluentpsssdsetroubleshootsanedgdmgnome-initial-setupsshdavahipostfixtcpdumpcentosapachemysq

例2   换行输出[root@localhost ~]# awk -F: '{printf "%s\n",$1}' /etc/passwd   # 加\n     就可以换行  

root

bin

daemon

adm

lp

sync

shutdown

halt

mail

operator

games


例3   : 在输出的字母前面添加自定义煮饭吃username大写

[root@localhost ~]# awk -F: '{printf "USERNAME: %s\n",$1}' /etc/passwd

USERNAME: root

USERNAME: bin

USERNAME: daemon

USERNAME: adm

USERNAME: lp

USERNAME: sync

USERNAME: shutdown

例4   对$1  和$NF   都做格式化输出

[root@localhost ~]# awk -F: '{printf "USERNAME: %s %s\n",$1,$NF}' /etc/passwd

USERNAME: root /bin/bash

USERNAME: bin /sbin/nologin

USERNAME: daemon /sbin/nologin

USERNAME: adm /sbin/nologin

USERNAME: lp /sbin/nologin

USERNAME: sync /bin/sync

USERNAME: shutdown /sbin/shutdown

USERNAME: halt /sbin/halt

USERNAME: mail /sbin/nologin

USERNAME: operator /sbin/nologin

例5   对$1  和¥NF   都做格式化输出,在两个之间添加一串===========进行输入

[root@localhost ~]# awk -F: '{printf "USERNAME: %s======= %s\n",$1,$NF}' /etc/passwd

USERNAME: root======= /bin/bash

USERNAME: bin======= /sbin/nologin

awk  修饰符

N:  显示宽度 

-:  左对齐  一个字母占一个宽度,默认是右对齐

例1  :显示时用10个字符串右对齐,如果要显示的字符串不够10个宽度,以字符串左边自动添加,一个字母占一个宽度,默认是右对齐

例2  : 使用10个宽度,左对齐显示

[root@localhost ~]# awk -F: '{printf "%-10s\n",$1}' /etc/passwd

root     

bin     

daemon   

adm     

lp       

sync     

shutdown 

halt     

mail     

operator

例3 

[root@localhost ~]# awk -F: '{printf "USERNAME: %-15s %15s\n",$1, $NF}' /etc/passwd

USERNAME: root                  /bin/bash

USERNAME: bin                /sbin/nologin

USERNAME: daemon            /sbin/nologin

USERNAME: adm                /sbin/nologin

USERNAME: lp                /sbin/nologin

USERNAME: sync                  /bin/sync

USERNAME: shutdown          /sbin/shutdown

使用开始和结束来输出

1  )  vim test.awk 

2)  输入

BEGIN{

        print "UserID\t\t\tShell"

        print "---------------------------"

        FS=":"

}

$3>=500 && $NF=="/sbin/nologin"{

        printf "%-20s %-20s\n",$1,$NF

}

END {

    print "---------------------------"

}

[root@localhost ~]# awk -f test.awk /etc/passwd

UserID Shell

---------------------------

24.4   实战-shell脚本实战

24.4.1   检查服务器是否收到DDOS   攻击脚本

思路:通过netstat  查看netstat  查看网络连接数,如果一个IP地址对服务器建立很多连接数  比如一分钟产生了100个连接,就认为发生了DDOS   

搭建环境

首先安装一个Apache  

[root@localhost ~]# yum -y install httpd

启动并写入

2)[root@localhost ~]# systemctl start httpd && echo "xuegod"> /var/www/html/index.html

3

查看端口

4)  找出访问的IP地址

  [root@localhost ~]# netstat -ntu | awk '{print $5}'

servers)

Address

192.168.24.1:12353

5)  找到具体的IP地址

[root@localhost ~]# netstat -ntu | awk '{print $5}'| cut -d: -f1

servers)

Address

192.168.24.1

[root@localhost ~]# netstat -ntu | awk '{print $5}'| cut -d: -f1 | sort | uniq -c | sort -n

注释   截取外网IP 和端口     截取外网的IP以:  为分隔符      |   排序  |   排除相同的记录  |  排序并统计


测试  ,模式DDOS 

6)  增加权限   

[root@localhost ~]# chmod +x ddos-test.sh

ab   命令  :  做压力测试的工具和性能的监控工具

语法:ab  -n   要产生的连接数总和,- c    同时打开的客户端数量   http://  连接

安装ab   命令

[root@localhost ~]# rpm -qf `which ab`    #   这个安装apeche  时,会自动安装上

httpd-tools-2.4.6-90.el7.centos.x86_64 

模拟DDOS   启动10个客户端对网站首页发起1000次访问  

  7)  清空防护墙  

[root@localhost ~]# iptables -F

  8)  [root@localhost ~]# ./ddos-test.sh   检查是否有错误

      1 192.168.24.1

      1 Address

      1 servers)

9)[root@localhost ~]# ab -n 1000 -c 10 http://192.168.24.171/index.html

  发现有了攻击

11)  使用这个区查看

[root@localhost ~]# ./ddos-test.sh

      1 192.168.24.1

      1 Address

      1 servers)

  1000 192.168.24.171


12) 


13  )  使用netstat  -ntu   区查看  

已经出现了ddos  攻击  

14   )  把ab  命令执行一遍

15  )


你可能感兴趣的:(第二十四章 shell中色彩处理和AWK 使用技巧)