Linux云计算 |【第二阶段】SHELL-DAY5

主要内容:

awk命令、内置变量(FS、$0、$1、$2、NF、NR)、过滤时机(BEGIN{}、{}、END{})、处理条件(正则、&&、||、~\!~、==等)、awk数组、监控脚本、安全检测脚本

一、awk介绍

awk 是一种强大的文本处理工具,广泛用于 Unix 和 Linux 系统中。它是一种编程语言,专门用于处理结构化数据和生成格式化的报告。awk 的名字来源于其三位开发者 Alfred Aho、Peter Weinberger 和 Brian Kernighan 的姓氏首字母。

作用:基于模式匹配检查输入文本,逐行处理并输出;通常用在Shell脚本中,获取指定的数据;单独使用时,可对文本数据做统计;(精确搜索、数据统计

补充:awk过滤数据时支持仅打印某一列;

补充:处理文本时,若未指定分隔符,则默认将空格、Tab制表符等作为分隔符。

1、awk 基本用法

格式:awk 'pattern { action }' file

  • pattern:用于匹配输入行的条件。如果省略,awk 将对所有行执行 action
  • action:在匹配的行上执行的操作。
  • file:要处理的文件。如果省略,awk 将从标准输入读取数据。

常用 action 指令:

  • {print}   输出

补充:使用awk时,如果指令就是{print},且前面写了条件的情况下可以省略{print}

awk 的基本概念:

  1. 记录(Record):awk 将输入数据视为一系列记录。默认情况下,记录是由换行符分隔的行
  2. 字段(Field):每个记录由字段组成。默认情况下,字段是由空格或制表符分隔的。字段可以通过 \$1, \$2, \$3, ... 来访问
  3. 变量:awk 有许多内置变量,例如 NF(字段数)、NR(记录数)、FS(字段分隔符)等

2、awk 内置变量

说明:

  • \$0:文本当前行的全部内容(整行)
  • \$1\$2, ...:当前记录的第 1 个、第 2 个字段等(第1列、第2列,依此类推)
  • NF:当前记录中的字段数(有几列)
  • NR:当前记录的行号(类似sed中的"=")
  • FS:字段分隔符(默认是空格或制表符)
  • RS:记录分隔符(默认是换行符)
  • OFS:输出字段分隔符(默认是空格)
  • ORS:输出记录分隔符(默认是换行符)

3、awk 常见用法

1)特定字段打印

打印文件 file.txt 中每一行的第一个和第三个字段

awk '{ print \$1, \$3 }' file.txt

2)使用模式匹配

打印文件 file.txt 中包含 pattern 的行

awk '/pattern/ { print \$0 }' file.txt

3)计算字段的总和

计算文件 file.txt 中第一个字段的总和,并在处理完所有行后打印总和

awk '{ sum += \$1 } END { print sum }' file.txt

4)使用自定义字段分隔符

使用冒号 : 作为字段分隔符,并打印 /etc/passwd 文件中每一行的第一个字段。

awk -F':' '{ print \$1 }' /etc/passwd

5)使用变量

打印文件 file.txt 中每一行的第一个字段,并在前面加上变量 var 的值。

awk -v var="Hello" '{ print var, \$1 }' file.txt

 4、awk 常用选项

-F fs

  • 说明:指定输入字段分隔符(Field Separator)。
  • 示例:awk -F':' '{ print \$1 }' /etc/passwd
  • 解释:使用冒号 : 作为字段分隔符,并打印 /etc/passwd 文件中每一行的第一个字段。

-v var=value

  • 说明:定义一个变量并赋值。
  • 示例:awk -v var="Hello" '{ print var, \$1 }' file.txt
  • 解释:定义变量 var 并赋值为 "Hello",然后打印文件 file.txt 中每一行的第一个字段,并在前面加上变量 var 的值。

-f scriptfile

  • 说明:从指定的脚本文件中读取 awk 命令。
  • 示例:awk -f script.awk file.txt
  • 解释:从 script.awk 文件中读取 awk 命令,并应用于 file.txt 文件。

-v OFS=output_field_separator

  • 说明:指定输出字段分隔符(Output Field Separator)。
  • 示例:awk -v OFS="," '{ print \$1, \$2, \$3 }' file.txt
  • 解释:使用逗号 , 作为输出字段分隔符,并打印文件 file.txt 中每一行的前三个字段。

-v ORS=output_record_separator

  • 说明:指定输出记录分隔符(Output Record Separator)。
  • 示例:awk -v ORS="\n\n" '{ print \$0 }' file.txt
  • 解释:使用两个换行符 \n\n 作为输出记录分隔符,并打印文件 file.txt 中的每一行。

-v FS=input_field_separator

  • 说明:指定输入字段分隔符(Field Separator)。
  • 示例:awk -v FS="," '{ print \$1 }' file.csv
  • 解释:使用逗号 , 作为输入字段分隔符,并打印文件 file.csv 中每一行的第一个字段。

-v RS=input_record_separator

  • 说明:指定输入记录分隔符(Record Separator)。
  • 示例:awk -v RS="\n\n" '{ print \$0 }' file.txt
  • 解释:使用两个换行符 \n\n 作为输入记录分隔符,并打印文件 file.txt 中的每一行。

-v NF=number_of_fields

  • 说明:指定每行的字段数。
  • 示例:awk -v NF=3 '{ print \$1, \$2, \$3 }' file.txt
  • 解释:指定每行有 3 个字段,并打印文件 file.txt 中每一行的前三个字段。

-v NR=number_of_records

  • 说明:指定处理的记录数。
  • 示例:awk -v NR=5 '{ print \$0 }' file.txt
  • 解释:只处理文件 file.txt 中的前 5 行,并打印每一行。


awk变量练习示例1:

[root@svr7 ~]# cat test     //测试文件
hello the world
welcome to beijing

例如:不加条件,输出所有

[root@svr7 opt]# awk '{print}' test
hello the world
welcome to beijing

例如:输出以h开头的行

[root@svr7 opt]# awk '/^h/{print}' test
hello the world

例如:输出所有行的第1列

[root@svr7 opt]# awk '{print $1}' test
hello
Welcome

例如:输出所有行的第1列和第3列

[root@svr7 opt]# awk '{print $1,$3}' test
hello world
welcome beijing

例如:输出以w开头,$0整行内容,第3列

[root@svr7 opt]# awk '/^w/{print $0,$3}' test
welcome to beijing beijing

例如:输出以w开头,$0整行内容,当前行的行号

[root@svr7 opt]# awk '/^w/{print $0,NR}' test
welcome to beijing 2

例如:输出以w开头,$0整行内容,当前行的列号

[root@svr7 opt]# awk '/^w/{print $0,NF}' test  
welcome to beijing 3

例如:输出每行最后一个字段(列)

[root@svr7 ~]# awk -F: '{print $NF}' /etc/passwd
/bin/bash
/sbin/nologin
/sbin/nologin
/sbin/nologin

例如:从脚本文件中读取 awk 命令

[root@svr7 opt]# awk -f script.awk example.csv

例如:使用逗号作为输出字段分隔符,并打印每一行的前两个字段

[root@svr7 opt]# awk -v OFS="," '{ print \$1, \$2 }' example.csv

例如:使用两个换行符作为输出记录分隔符,并打印每一行

[root@svr7 opt]# awk -v ORS="\n\n" '{ print \$0 }' example.csv

例如:输出passwd文件中以【:】分隔的第1、7个字段,需要显示的不同字段之间,以逗号【,】隔开(  -F 可指定分隔符)

[root@svr7 opt]# awk -F: '/bash$/{print $1,$7}' /etc/passwd
root /bin/bash
student /bin/bash
lisi /bin/bash
...

通过“常量”显示字段之间的空白,增加辨识(awk的print指令不仅可以打印变量,还可以打印常量)

[root@svr7 opt]# awk -F: '/bash$/{print $1,"的解释器:"$7}' /etc/passwd
root 的解释器:/bin/bash
student 的解释器:/bin/bash
lisi 的解释器:/bin/bash
...
  • 注意:输出“常量”时使用双引号【“”】

补充:awk输出特点,【,】显示为一个空格;直接打空格或多个空格,都不显示

[root@svr7 opt]# awk -F: '/bash$/{print $1     $7}' /etc/passwd
root/bin/bash
student/bin/bash
lisi/bin/bash
...

补充:awk可识别多种单个的字符,比如以“:”或“/”分隔,输出第1、10字段

[root@svr7 opt]# awk -F [:/] '{print $1,$10}' /etc/passwd
root bash
bin nologin
daemon nologin
...

awk变量练习示例1:

例如:输出/etc/hosts映射文件内以127或者192开头的记录

[root@svr7 ~]# awk  '/^(127|192)/' /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
192.168.4.5  svr5.tarena.com svr5

例如:结合管道过滤命令输出根分区的磁盘剩余空间

[root@svr7 ~]# df -h /
文件系统        容量     已用     可用     已用%     挂载点
/dev/sda2      19G     7.2G     14G     40%       /
[root@svr7 opt]# df -h / | tail -1 | awk '{print$4}'
14G
[root@svr7 opt]# df -h | awk '/\/$/{print$4}'    //【/$】以根结尾,需加转义符【\】
14G

例如:检查登录失败的IP地址有哪些

[root@svr7 opt]# cat /var/log/secure
Apr  8 09:25:37 svr7 sshd[2497]: Failed password for root from 192.168.4.254 port 55446 ssh2
[root@svr7 opt]# awk '/Failed/{print $11}' /var/log/secure
192.168.4.254

例如:检查内存的剩余容量

[root@svr7 opt]# freetotal     used       free      shared  buff/cache   available
Mem:  1015292   397320   200064      7888      417908      410044
[root@svr7 opt]# free | awk '/Mem/{print"内存剩余容量"$4}'
内存剩余容量200216

例如:利用awk提取本机的网络流量

- 通过ifconfig eth0查看网卡信息,其中包括网卡流量:

[root@svr7 opt]# ifconfig eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500inet 192.168.4.7  netmask 255.255.255.0  broadcast 192.168.4.255inet6 fe80::b7fc:281e:69b8:c18  prefixlen 64  scopeid 0x20<link>ether 52:54:00:64:12:44  txqueuelen 1000  (Ethernet)RX packets 21386  bytes 2395273 (2.2 MiB)RX errors 0  dropped 0  overruns 0  frame 0TX packets 4196  bytes 508274 (496.3 KiB)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

RX为接收数据量,TX为发送数据量。packets以数据包数量为单位,bytes以字节为单位

- 过滤接收数据的流量

[root@svr7 opt]# ifconfig eth0 | awk '/RX p/{print"服务器eth0接收流量是"$5"字节"}'      //过滤接收数据的流量
服务器eth0接收流量是2436341字节

- 过滤发送数据的流量

[root@svr7 opt]# ifconfig eth0 | awk '/TX p/{print"服务器eth0接收流量是"$5"字节"}'     //过滤发送数据的流量
服务器eth0发送流量是548040字节

二、awk 过滤时机(BEGIN{}、逐行处理{}、END{})

在 awk 中,处理文本数据的过程可以分为三个主要阶段:BEGIN 块、逐行处理块{} 和 END 块。每个阶段都有其特定的用途和执行时机。以下是这三个阶段的详细说明:

1、BEGIN 块

  • 执行时机:在读取任何输入记录之前执行。
  • 用途:用于初始化变量、设置输入/输出字段分隔符、打印标题等。
  • 语法:BEGIN { action }
awk 'BEGIN { FS=","; OFS="\t"; print "Name\tAge\tCity" } { print \$1, \$2, \$3 }' example.csv

解释:
BEGIN 块中设置了输入字段分隔符 FS 为逗号 ,,输出字段分隔符 OFS 为制表符 \t。
打印标题行 "Name\tAge\tCity"。
逐行处理块中打印每一行的字段。

2、逐行处理块

  • 执行时机:在读取每一行输入记录时执行。
  • 用途:用于处理每一行的数据,进行字段提取、条件判断、计算等操作。
  • 语法:{ action }
awk '{ if (\$2 > 30) print \$1, \$2, \$3 }' example.csv

解释:
逐行处理块中检查每一行的第二个字段是否大于 30。
如果条件满足,则打印该行的第一个、第二个和第三个字段。

3、END 块

  • 执行时机:在读取所有输入记录之后执行。
  • 用途:用于输出汇总信息、计算总和、打印统计结果等。
  • 语法:END { action }
awk 'BEGIN { FS=","; OFS="\t"; print "Name\tAge\tCity" } { sum += \$2 } END { print "Total Age:", sum }' example.csv

解释:
BEGIN 块中设置了输入字段分隔符 FS 为逗号 ,,输出字段分隔符 OFS 为制表符 \t。
打印标题行 "Name\tAge\tCity"。
逐行处理块中累加每一行的第二个字段(年龄)。
END 块中打印总年龄 "Total Age:" 和累加结果 sum

总结:

  1. BEGIN{ }  行前处理,读取文件内容前执行,指令执行1次
  2. { }             逐行处理,读取文件过程中执行,指令执行n次
  3. END{ }      行后处理,读取文件结束后执行,指令执行1次

例如:只做BEGIN{}预处理的时候,可以没有操作文件

[root@svr7 ~]# awk 'BEGIN{a=34;print a+12}'
46
[root@svr7 ~]# awk 'BEGIN{print "HELLOWORLD"}'
HELLOWORLD
[root@svr7 ~]# awk 'BEGIN{print x+1}'  //x可以不定义,直接用,默认值位0
1

例如:只做END{}处理的时候,需要有操作文件(只输出处理结果)

[root@svr7 opt]# awk 'END{print "BYE"}' user
BYE

例如:

[root@svr7 opt]# awk 'BEGIN{print NR}{print}END{print NR}' user
0
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@svr7 opt]# awk 'BEGIN{print NR}END{print NR}' user
0      //预处理时,行数为0
5      //当文本全部处理完之后执行,行数为已读入文本的行数

例如:统计系统中使用/bin/bash作为登录Shell的用户总个数

  • 思路1:预处理时赋值变量x=0
  • 思路2:然后逐行读入/etc/passwd文件,如果发现登录Shell是/bin/bash则x加1
  • 思路3:全部处理完毕后,输出x的值即可
[root@svr7 opt]# awk 'BEGIN{x=0}/\/bin\/bash$/{x++}END{print x}' /etc/passwd
7

例如:格式化输出/etc/passwd文件,要求第一行为列表标题,中间打印用户的名称、UID、家目录信息,最后一行提示一共已处理文本的总行数,如图所示:

  • 思路1:
[root@svr7 opt]# awk 'BEGIN{print"User\tUID\tHome"}'
User UID Home

【\t】显示Tab制表位,必须需写在双引号【“”】内才能生效

  • 思路2:
[root@svr7 opt]# awk -F: '{print $1"\t"$3"\t"$6}' user
root 0 /root
bin 1 /bin
daemon 2 /sbin
adm 3 /var/adm
lp 4 /var/spool/lpd
  • 思路3:

[root@svr7 opt]# awk 'END{print"Total: "NR,"lines."}' user
Total: 5 lines.

结果:

[root@svr7 opt]# awk -F: 'BEGIN{print"User\tUID\tHome"} {print$1"\t"$3"\t"$6} END{print"Total:",NR,"lines."}' user
User    UID    Home
root     0     /root
bin      1     /bin
daemon   2     /sbin
adm      3     /var/adm
lp       4     /var/spool/lpd
Total: 5 lines.

三、awk 处理条件

概述:所有的行全部处理并输出;限制处理的条件;根据多个条件来处理指定的行

回顾格式:awk [选项] ‘[条件] {指令}’ 被处理文件...

条件的表现形式:

  • ① 正则表达式:/表达式/、~、!~
  • ② 数值/字符串比较:==、!=、>、>=、
  • ③ 逻辑比较:&& 逻辑与、||逻辑或
  • ④ 运算符:+、-、*、/、%、++、--、+=、-=、*=、/=

1)正则表达式

  • /正则表达式/
  • ~包含、!~不包含

例如:输出其中以bash结尾的行

[root@svr7 opt]# awk -F: '/bash$/' /etc/passwd
root:x:0:0:root:/root:/bin/bash
student:x:1000:1000:Student:/home/student:/bin/bash
...

例如:输出包含root的行

[root@svr7 opt]# awk -F: '/root/' /etc/passwd 
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

例如:输出root或adm账户的用户名和UID信息

[root@svr7 opt]# awk -F: '/^(root|adm)/{print $1,$3}' /etc/passwd  =
root 0
adm 3

例如:~包含、!~不包含

[root@svr7 opt]# awk -F: '$1~/root/{print}' /etc/passwd 
root:x:0:0:root:/root:/bin/bash[root@svr7 opt]# awk -F: '$1~/root/' /etc/passwd 
root:x:0:0:root:/root:/bin/bash

补充:使用awk时如果指令就是{print},且前面写了条件的情况下可以省略{print}

例如:输出登录Shell不以nologin结尾(即对第7个字段做!~反向匹配)的用户名、登录Shell信息

[root@svr7 opt]# awk -F: '$7!~/nologin$/{print $1,$7}' /etc/passwd 
root /bin/bash
sync /bin/sync
shutdown /sbin/shutdown
...

2)数值比较

  • ==等于、!=不等于、>大于、>=大于或等于、

例如:输出第1行

[root@svr7 opt]# awk -F: 'NR==1' /etc/passwd 
root:x:0:0:root:/root:/bin/bash

例如:输出第2行第7列

[root@svr7 opt]# awk -F: 'NR==2{print $7}' /etc/passwd 
/sbin/nologin

例如:输出行号小于或等于3

[root@svr7 opt]# awk -F: 'NR<=3' /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin

例如:输出账户UID大于等于1000的账户名称和UID信息(普通用户)

[root@svr7 opt]#  awk -F: '$3>=1000{print $1,$3}' /etc/passwd
student 1000
lisi 1001
zhangsan 1002
...

例如:找解释器是/bin/bash的用户

[root@svr7 opt]# awk -F: '$7=="/bin/bash"' /etc/passwd
root:x:0:0:root:/root:/bin/bash
student:x:1000:1000:Student:/home/student:/bin/bash
lisi:x:1001:1001::/home/lisi:/bin/bash
...

例如:找解释器不是/sbin/nologin的用户

[root@svr7 opt]# awk -F: '$7!="/sbin/nologin"' /etc/passwd 
root:x:0:0:root:/root:/bin/bash
sync:x:5:0:sync:/sbin:/bin/sync
...

例如:找解释器不是/sbin/nologin的用户及输出第1列包含root的行

[root@svr7 opt]# awk -F: '$1=="root"' /etc/passwd 
root:x:0:0:root:/root:/bin/bash
[root@svr7 opt]# awk -F: '$1~/root/' /etc/passwd
root:x:0:0:root:/root:/bin/bash
  • 注意:==比~包含更严格匹配,~包含稍微宽松匹配

例如:查看包含2个及以上字段的行

[root@svr7 opt]# awk 'NF>=2{print}' /etc/passwd

3)逻辑比较

  • && 逻辑与:期望多个条件多成立;
  • || 逻辑或:只要有一个条件成立即满足要求;

例如:找uid范围是10~20的行

[root@svr7 opt]# awk -F: '$3>=10&&$3<=20' /etc/passwd  
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

例如:找行号2~10行

[root@svr7 opt]# awk 'NR>=2&&NR<=10' /etc/passwd
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

例如:找uid是0~4或者1001以上的行

[root@svr7 opt]# awk -F: '$3<5||$3>1001' /etc/passwd
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
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
zhangsan:x:1002:1002::/home/zhangsan:/bin/bash
wangwu:x:1003:1003::/home/wangwu:/bin/bash
abc01:x:1004:1004::/home/abc01:/bin/bash
Tom:x:1005:1005::/home/Tom:/bin/bash

4)运算符

  • +、-、*、/、%
  • ++、--、+=、-=、*=、/=

例如:不定义x,默认为0

[root@svr7 opt]# awk 'BEGIN{x++;print x}'
1
[root@svr7 opt]# awk 'BEGIN{x=8;print x+=2}'
10
[root@svr7 opt]# awk 'BEGIN{print x+=2}'
2
[root@svr7 opt]# awk 'BEGIN{print 2*2}'
4
[root@svr7 opt]# awk 'BEGIN{print 10%3}'
1

例如:显示偶数行

[root@svr7 opt]# awk 'NR%2==0' user
bin:x:1:1:bin:/bin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin

例如:显示奇数行

[root@svr7 opt]# awk 'NR%2==1' user
root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

例如:统计文本的总字段个数

[root@svr7 opt]# awk 'BEGIN{i=0}{i+=NF}END{print i}' user
5

四、awk 数组

1)定义数组

格式:数组名[下标]=元素值      //数组名[下标]=下标对应的值(类似变量)

解释:数组是一个可以存储多个值的变量;

2)调用数组

格式:数组名[下标]

3)遍历数组(awk命令使用数组和for循环实现高级搜索)

用法:for( 变量 in 数组名 ){print 数组名[变量]}

[root@svr7 /]# awk 'BEGIN{a=11;b=22;print a,b}'     //变量
11 22
[root@svr7 /]# awk 'BEGIN{a[1]=10;a[2]=20;print a[1],a[2]}'    //数组[下标]
10 20

解释:使用awk测试数组创建了一个数组名字叫a,分别定义两个下标与对应的两个值,然后用print查看了a[1]的值和a[2]的值;

例如:创建素材文件data,该文件里面有三行信息;

[root@svr7 ~]# cat data
abc
xyz
abc

使用逐行任务{a[$1]++}走完所有行的第1列得到:

1 abc  ->   a[abc]++  ->  a[abc]=1

解释:起始a[abc]默认为0。匹配1次+1(0+1=1)

2 xyz  ->   a[xyz]++  ->  a[xyz]=1

解释:起始a[xyz]默认为0。匹配1次+1(0+1=1)

3 abc  ->   a[abc]++  ->  a[abc]=2

解释:a[abc]已匹配1次。再匹配1次+1(1+1=2)

{a[$1]++} 对文本的每行内容以第一个字段【$1】为数组下标进行计数。若遇第一个字段相同的情况,计数累加。

[root@svr7 ~]# awk '{a[$1]++}END{print a["abc"],a["xyz"]}' data
2 1

解释:根据上述结果,得到如果使用{a[$1]++}走完所有行,便可收集到a[xyz]=1和a[abc]=2的结果,所以在最后使用END任务输出a[“xyz”]和a[“abc”]的值就是 1和 2

[root@svr7 ~]# awk '{a[$1]++}END{for(i in a){print i}}' data
abc
xyz
[root@svr7 ~]# awk '{a[$1]++}END{for(i in a){print a[i]}}' data
2
1
[root@svr7 ~]# awk '{a[$1]++}END{for(i in a){print i,a[i]}}' data
abc 2
xyz 1

解释:使用for循环,循环显示数组a的下标,与值,其中for(i in a)里面的i是变量,代表下标,in是语法不能变,a是数组名

例如:

[root@svr7 ~]# awk 'BEGIN{a[0]=11;a[1]=88;print a[1],a[0]}'
88 11
[root@svr7 ~]# awk 'BEGIN{a++;print a}'
1
[root@svr7 ~]# awk 'BEGIN{a[0]++;print a[0]}'    //”a[0]”相当于1个变量
1
[root@svr7 ~]# awk 'BEGIN{a[0]=0;a[1]=11;a[2]=22; for(i in a){print i,a[i]}}'
0 0
1 11
2 22


案例:针对Web访问日志计算访问量排名

思路分析:

① 获取关键词:客户机地址、访问次数

[root@svr7 /]# cd /var/log/httpd/   //Apache日志目录
[root@svr7 httpd]# ls
access_log  error_log
[root@svr7 httpd]# wc -l access_log    //access_log为登入httpd来访者的记录
4 access_log
[root@svr7 httpd]# tail -1 access_log
192.168.4.7 - - [08/Apr/2021:16:36:15 +0800] "GET /favicon.ico HTTP/1.1" 404 209 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0"
  • 关键词:access_log日志中第1个字段即对应客户机的IP

② 利用awk提取客户机IP地址、访问次数

[root@svr7 httpd]# awk '{print $1}' /var/log/httpd/access_log
192.168.4.7
192.168.4.7
192.168.4.7
192.168.4.7

③ 以$1作为下标,定义数组ip,【ip[$1]】

④ 利用for循环输出数组下标、对应数组元素的值

[root@svr7 httpd]# awk '{ip[$1]++}END{print ip["192.168.4.7"]}' /var/log/httpd/access_log
8
[root@svr7 httpd]# awk '{ip[$1]++}END{for(i in ip){print i,ip[i]}}' /var/log/httpd/access_log
192.168.4.7 8

补充:利用sort可提取结果访问次数排名

[root@svr7 /]# awk '{ip[$1]++}END{for(i in ip){print i,ip[i]}}' /var/log/httpd/access_log | sort -nr
192.168.4.7 8

补充:利用sort对提取结果排序

[-n]  按数字生序排列

[-k]   针对指定的列进行排序

[-r]   反向排序


案例:安全检测脚本(防止远程ssh暴力破解密码)

任务需求:统计登录服务器失败的用户IP记录,/var/log/secure是系统的安全日志,如果有人登录服务器而密码输入错误则会记录到该文档中;(测试前登录服务器并故意输入错误密码)

思路分析:

① ssh登录的安全日志为/var/log/secure

[root@svr7 ~]# ls /var/log/secure
/var/log/secure
[root@svr7 ~]# grep 'Failed' /var/log/secure
Apr  8 09:25:37 svr7 sshd[2497]: Failed password for root from 192.168.4.254 port 55446 ssh2

② 分析日志文件格式

Apr  8 09:25:37 svr7 sshd[2497]: Failed password for root from 192.168.4.254 port 55446 ssh2

  • 关键词:Failed password 及 登录失败的IP(在记录中的第11列)

② 找出用户名以及密码错误的规律,并提取有数据

[root@svr7 ~]# awk '/Failed password/{print}' /var/log/secure
Apr  8 09:25:37 svr7 sshd[2497]: Failed password for root from 192.168.4.254 port 55446 ssh2
Apr  9 09:27:55 svr7 sshd[2649]: Failed password for root from 192.168.4.254 port 48504 ssh2
Apr  9 09:27:59 svr7 sshd[2649]: Failed password for root from 192.168.4.254 port 48504 ssh2

③ 对有效数据进行汇总统计,实现黑名单过滤动能

[root@svr7 ~]# awk '/Failed password/{ip[$11]++}END{for(i in ip){print i,ip[i]}}' /var/log/secure
192.168.4.254 3
[root@svr7 ~]# ls /var/log/      //安全日志文件
secuer-20210409 secure-20210312


案例:监控脚本

编写脚本监控本机各项数据指标:

  • ① CPU负载:uptime、top
  • ② 内存剩余容量:free,[-h]显示单位
  • ③ 磁盘剩余容量:df,[-h]显示单位
  • ④ 计算机账户数量:cat /etc/passwd | wc -l
  • ⑤ 当前登录账户数量:who | wc -l
  • ⑥ 当前开启的进程数量:ps -aux | wc -l
  • ⑦ 网卡流量:ifconfig
  • ⑧ 已安装的软件包数量:rpm -qa | wc -l

思路分析:

① 查看CPU负载、系统登录时间(或top)

[root@svr7 /]# uptime10:13:12 up  1:39,  1 user,  load average: 0.00, 0.01, 0.05
[root@svr7 /]# uptime | awk '{print $NF}'
0.05
  • 关键词:15分钟平均负载($NF)
[root@svr7 /]# uptime | awk '{print "cpu15分钟平均负载量是:" $NF}'
cpu15分钟平均负载量是:0.05

② 查看内存容量

[root@svr7 /]# free -htotal    used      free      shared  buff/cache   available
Mem:     991M     383M      178M      7.7M     429M        405M
Swap:    2.0G      0B       2.0G
[root@svr7 log]# free -h | awk '/^Mem/{print}'
Mem:     991M     384M       178M       7.7M     429M      404M
  • 关键词:Mem内存,free剩余($4)
[root@svr7 /]# free -h | awk '/^Mem/{print "剩余内存容量是:"$4}'
剩余内存容量是:178M

③ 查看磁盘剩余容量

[root@svr7 /]# df -h
文件系统                   容量  已用  可用 已用% 挂载点
/dev/mapper/centos-root   17G  3.7G   14G   22%  /
  • 关键词:根分区,可用容量($4)
[root@svr7 /]# df -h | awk '/\/$/{print "服务器根分区剩余容量是:"$4}'
服务器根分区剩余容量是:14G

④ 计算机账户数量

[root@svr7 opt]# wc -l /etc/passwd
48 /etc/passwd
  • 关键词:统计/etc/passwd记录行数($1)

方法1:

[root@svr7 opt]# wc -l /etc/passwd | awk '{print $1}'
48

方法2:

n=$(wc -l /etc/passwd)    //定义变量
n1=${n%%/*}    //去尾
echo "服务器账户总是:$n1个"

方法3:

[root@svr7 opt]# awk 'BEGIN{i=0}{i=NR}END{print i}' /etc/passwd
48

⑤ 当前登录账户数量

[root@svr7 opt]# who
root     pts/0        2021-04-09 09:01 (192.168.4.254)
  • 关键词:统计who记录行数
[root@svr7 opt]# echo $(who | wc -l)
1

⑥当前开启的进程数量

[root@svr7 opt]# ps -aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.6 128304  6848 ?        Ss   08:33   0:01 /usr/lib/system
root         2  0.0  0.0      0     0 ?        S    08:33   0:00 [kthreadd]
root         3  0.0  0.0      0     0 ?        S    08:33   0:00 [ksoftirqd/0]
...
  • 关键词:统计ps记录行数
[root@svr7 opt]# echo $(ps aux | wc -l)
180

编写脚本

[root@svr7 opt]# vim test.sh
#!/bin/bash
while :
do
clear    //清空屏幕显示uptime | awk '{print "cpu15分钟平均负载量是:" $NF}'df -h | awk '/\/$/{print "服务器根分区剩余容量是:"$4}'free -h | awk '/^Mem/{print "剩余内存容量是:"$4}'n=$(wc -l /etc/passwd)n1=${n%%/*}echo "服务器账户总是:$n1个"echo  "当前登录账户数量是:$(who | wc -l)个"x=$(ps aux | wc -l)echo "当前开启的进程数量是:$x个"
sleep 3
done

测试:

[root@svr7 opt]# bash test.sh
cpu15分钟平均负载量是:0.05
服务器根分区剩余容量是:14G
剩余内存容量是:174M
服务器账户总是:48 个
当前登录账户数量是:2个
当前开启的进程数量是:183个

扩展知识:

awk 和 sed 都是 Unix 和 Linux 系统中常用的文本处理工具,但它们的设计目的和使用场景有所不同。以下是它们的主要区别:

1、awk:(更适合处理结构化数据和生成报告,支持复杂的文本处理任务)

设计目的:awk 是一种编程语言,专门用于处理结构化数据和生成格式化的报告。它主要用于数据提取和报告生成,适合处理包含字段的文本文件(如 CSV 文件)。awk 提供了丰富的内置变量和函数,支持条件判断、循环、数组等高级功能。

语法和功能:

  • 语法:awk 'pattern { action }' file
  • 支持字段操作:\$1, \$2, \$3, ...
  • 支持内置变量:NF(字段数)、NR(记录数)、FS(字段分隔符)等
  • 支持条件判断、循环、数组等高级功能
  • 适合处理结构化数据和生成报告
# 打印文件中每一行的第一个和第三个字段
awk '{ print \$1, \$3 }' file.txt# 计算文件中第一个字段的总和
awk '{ sum += \$1 } END { print sum }' file.txt# 打印包含特定模式的行
awk '/pattern/ { print \$0 }' file.txt

2、sed:(更适合简单的文本编辑和转换任务,适合处理单行文本或简单的多行文本)

设计目的:sed 是一种流编辑器,主要用于对文本进行基本的编辑操作,如替换、删除、插入等。它适合用于简单的文本转换和处理任务,如批量替换文件中的字符串。sed 的语法相对简单,主要通过命令和正则表达式来操作文本。

语法和功能:

  • 语法:sed 's/pattern/replacement/' file
  • 支持基本的文本编辑操作:替换(s)、删除(d)、插入(i)、追加(a)等
  • 支持正则表达式
  • 适合简单的文本转换和处理任务
# 替换文件中的字符串
sed 's/old/new/g' file.txt# 删除包含特定模式的行
sed '/pattern/d' file.txt# 在每行前插入一行
sed 'i\Inserted line' file.txt

思维导图:

小结:

本篇章节为【第二阶段】SHELL-DAY5 的学习笔记,这篇笔记可以初步了解到 awk命令、内置变量、过滤时机、处理条件、awk数组、监控脚本、安全检测脚本


Tip:毕竟两个人的智慧大于一个人的智慧,如果你不理解本章节的内容或需要相关笔记、视频,可私信小安,请不要害羞和回避,可以向他人请教,花点时间直到你真正的理解

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1534655.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

基于微信平台的旅游出行必备商城小程序+ssm(lw+演示+源码+运行)

摘 要 随着社会的发展&#xff0c;社会的方方面面都在利用信息化时代的优势。互联网的优势和普及使得各种系统的开发成为必需。 本文以实际运用为开发背景&#xff0c;运用软件工程原理和开发方法&#xff0c;它主要是采用java语言技术和mysql数据库来完成对系统的设计。整个…

影视直冲?对接卡券特权充值接口对于用户来说有什么优势?

对用户来说有哪些优势&#xff1a; 便利性&#xff1a;用户可以直接在应用程序或网站上充值和使用卡券&#xff0c;无需通过多个平台或渠道&#xff0c;提高了用户体验。实时性&#xff1a;卡券充值和使用状态可以实时更新&#xff0c;用户可以立即看到余额变化和卡券状态。安…

移动硬盘无法读取?别慌!这些方法助你恢复数据!

在我们的日常工作和生活中&#xff0c;移动硬盘作为重要的数据存储工具&#xff0c;承载着珍贵资料。然而&#xff0c;移动硬盘无法被电脑读取的情况时有发生&#xff0c;令人焦急。别慌&#xff0c;下面为大家详细介绍恢复移动硬盘数据的有效方法。 一、检查硬件连接和驱动问题…

麒麟桌面操作系统:查看最近安装与卸载的软件包

麒麟桌面操作系统&#xff1a;查看最近安装与卸载的软件包 1、查看最近安装的deb包2、查看最近卸载的deb包 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在麒麟桌面操作系统中&#xff0c;快速查看最近安装与卸载的软件包非常简单。这里有…

【多因子分组箱线图】:附Origin详细画图教程

目录 No.1 理解箱线图 1 什么是箱线图 2 箱线图的组成 No.2 画图流程 1 导入数据并绘图 2 设置绘图细节 3 设置坐标轴 4 效果图 No.1 理解箱线图 1 什么是箱线图 箱线图&#xff0c;又称箱形图、盒须图或盒式图&#xff0c;用于体现数据分散情况的统计图。在视觉上辅助…

大数据新视界 --大数据大厂之数据挖掘入门:用 R 语言开启数据宝藏的探索之旅

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

猜数-while-python

题目要求&#xff1a; 设置一个范围1-100的随机整数变量&#xff0c;通过while循环&#xff0c;诶和input语句&#xff0c;判断输入的数字是否等于随机数 无限次机会&#xff0c;直到猜中为止每一次不猜中都&#xff0c;会提示大了小了猜完数字后&#xff0c;提示裁了几次 imp…

干耳朵要掏吗?高性价比的可视挖耳勺推荐

干耳朵的耳朵属于比较干爽的内部环境&#xff0c;如果耳道中耳屎过多建议使用专业的工具来掏耳朵。在掏耳的过程建议用可视挖耳勺&#xff0c;可以通过内窥镜来实时查看耳道内的情况&#xff0c;更加安全和精准。但市面上的可视挖耳勺枪品质良莠不齐&#xff0c;一些黑心商家只…

此mac无法连接Apple媒体服务,因为“”出现问题。

出现问题&#xff1a; 这是因为mac登陆过别人的appId下载过软件&#xff0c;但是没有完全退出登陆 解决 打开偏好设置&#xff0c;点击头像&#xff0c;点击媒体与已购项目&#xff0c;能看到弹框内AppleID登陆的应用&#xff0c;打开对应的那个应用&#xff0c;我这里是音…

Linux(CentOS8)服务器安装RabbitMQ

我安装了很久都没有成功, 各种问题, 每次的异常都不一样, 现将成功安装过程做个总结 安装前工作 确保已经安装了一些基础工具和组件库 下载安装包 https://www.erlang.org/patches/otp-24.3.4.5 https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.9.15/ra…

后台数据库查询记录

一、根据日期按天分组查询倒序 //mapper public List<Date> dateByPatientId(FollowScheme followScheme); <select id"dateByPatientId" parameterType"com.ruoyi.follow.domain.FollowScheme" resultType"java.util.Date">SELECT…

视频推镜拍摄SDK解决方案,创新短视频玩法

在当今社交媒体盛行的时代&#xff0c;短视频已成为人们分享生活、展示创意的重要方式。美摄科技推出的视频推镜拍摄SDK解决方案&#xff0c;为用户提供了一种全新的短视频创作体验。 一、什么是视频推镜拍摄SDK解决方案&#xff1f; 美摄科技的视频推镜拍摄SDK解决方案是一种…

攻防演练篇:攻防演练场景中面临的常见加密威胁-HTTP隐蔽隧道

1 概述 在网络安全领域&#xff0c;隐蔽隧道是一种基于主流常规协议将恶意流量伪装成正常通信起到夹带偷传数据、下发控制指令等作用&#xff0c;同时对数据进行加密以最大限度的规避网络安全设备检测的传输技术。由于隐蔽隧道更容易绕过网络安全设备的检测&#xff0c;因此黑…

scratch中秋节——孔明灯祈福

小虎鲸Scratch资源站-免费少儿编程Scratch作品源码,素材,教程分享网站! 中秋节是中国的传统佳节&#xff0c;象征着团圆与美好。在这个特别的节日里&#xff0c;除了赏月、吃月饼&#xff0c;放飞孔明灯也是一种独特的祈福方式。而如今&#xff0c;你可以在小虎鲸Scratch资源站…

51.【C语言】字符函数和字符串函数(strcpy函数)

承接50.【C语言】字符函数和字符串函数(上) 点我跳转 5.strcpy函数 *简单使用 cplusplus的介绍 点我跳转 strcpy:string copy 翻译: 复制字符串 复制由source指向的C字符串到由destionation指向的数组中,包括\0(终止0字符)(在\0那里停止复制) 为了防止溢出,由destionation指…

CDGA|如何实施非常精准的数据治理策略?

在信息化高速发展的今天&#xff0c;数据已成为企业最重要的生产要素之一&#xff0c;其价值日益凸显。然而&#xff0c;随着数据量的爆炸性增长&#xff0c;如何精准地管理和控制数据成为企业亟待解决的问题。本文将从设定目标、制定策略、组织结构建设、制度流程规范以及技术…

【大模型专栏—进阶篇】语言模型创新大总结——“三派纷争”

大模型专栏介绍 &#x1f60a;你好&#xff0c;我是小航&#xff0c;一个正在变秃、变强的文艺倾年。 &#x1f514;本文为大模型专栏子篇&#xff0c;大模型专栏将持续更新&#xff0c;主要讲解大模型从入门到实战打怪升级。如有兴趣&#xff0c;欢迎您的阅读。 &#x1f4…

【JAVA入门】Day36 - 异常

【JAVA入门】Day36 - 异常 文章目录 【JAVA入门】Day36 - 异常一、异常结构体系综述1.1 错误&#xff08;Error&#xff09;1.2 异常&#xff08;Exception&#xff09;1.3 运行时异常&#xff08;RuntimeException&#xff09;1.4 其他异常 二、编译时异常和运行时异常三、异常…

JAVA智能辅导因材施教家教系统小程序源码

探索“智能辅导因材施教家教系统”的奥秘 &#x1f680; 开篇&#xff1a;未来教育的新篇章 在这个日新月异的时代&#xff0c;教育也在悄然发生着变革。你是否厌倦了千篇一律的教学模式&#xff1f;渴望为孩子找到那个真正“懂他”的老师&#xff1f;今天&#xff0c;就让我带…

JavaDS —— LRUCache

概念 LRU是Least Recently Used的缩写&#xff0c;意思是最近最少使用&#xff0c;它是一种Cache替换算法。 什么是Cache&#xff1f;狭义的Cache指的是位于CPU和主存间的快速RAM&#xff0c; 通常它不像系统主存那样使用DRAM技术&#xff0c;而使用昂贵但较快速的SRAM技术。…