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

news2024/11/25 19:26:34

主要内容:

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]# free
      total     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 1500
        inet 192.168.4.7  netmask 255.255.255.0  broadcast 192.168.4.255
        inet6 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 0
        TX 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 /]# uptime
 10: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 -h
         total    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.coloradmin.cn/o/2124927.html

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

相关文章

【主机入侵检测】Wazuh解码器详解

前言 Wazuh 是一个开源的安全平台&#xff0c;它使用解码器&#xff08;decoders&#xff09;来从接收到的日志消息中提取信息。解码器将日志信息分割成字段&#xff0c;以便进行分析。Wazuh解码器使用XML语法&#xff0c;允许用户指定日志数据应该如何被解析和规范化。解码器的…

TP发邮件的功能如何实现?tp框架发送邮件?

tp发邮件系统如何设置发信&#xff1f;tp配置邮箱发送邮件方法&#xff1f; TP发邮件的功能&#xff0c;作为企业级应用中的一个关键模块&#xff0c;其稳定性和高效性直接影响到企业的日常运营。AokSend将深入探讨TP发邮件的功能如何实现&#xff0c;从基础配置到高级应用&am…

监控易监测对象及指标之:全面监控Oracle数据库

随着企业业务的不断增长和复杂化&#xff0c;Oracle数据库作为关键的业务数据管理系统&#xff0c;其性能和稳定性对于保障业务连续性至关重要。为了确保Oracle数据库的高效运行和稳定性能&#xff0c;对其进行全面监控成为了一项必要的工作。本文将基于监控易工具&#xff0c;…

搭建大模型知识库流程,以及基于langchain实现大模型知识库案例

“ RAG检索增强生成是为了解决大模型知识不足的问题 ” 大模型主要面临三个问题&#xff1a; 垂直领域内的知识不足 大模型知识有时间限制 大模型幻觉问题 第一个问题产生的原因是因为&#xff0c;没有经过垂直领域数据训练的大模型普遍表现不好&#xff1b;其次是目前的大…

新160个crackme - 054-vcrkme01

运行分析 需破解Name和Code PE分析 C程序&#xff0c;32位&#xff0c;无壳 静态分析&动态调试 ida找到关键字符串&#xff0c;双击进入函数 主函数静态分析&#xff0c;注释如上&#xff0c;还需要了解sub_401000函数 对sub_401000函数进行分析&#xff0c;注释如上&#…

半导体设备系列(2) 半导体设备与工厂控制仿真器Demo编写

可以用CS架构编写这两个仿真器&#xff0c;将设备写成服务器&#xff0c;接收来自工厂控制程序的命令。后续加上半导体设备通信协议。 半导体设备服务器 1&#xff09;工程文件 QT core gui networkgreaterThan(QT_MAJOR_VERSION, 4): QT widgetsCONFIG c17# You ca…

linux 操作系统下的convertquota命令介绍和使用案例

linux 操作系统下的convertquota命令介绍和使用案例 convertquota命令介绍 convertquota是Linux系统中用于转换旧格式的用户和组配额文件的命令。它可以将旧格式的quota.user和quota.group文件转换为新格式的aquota.user和aquota.group文件。新格式的配额文件支持32位的uid/g…

有关WSL和docker的介绍

目录标题 如何利用在windows上配置docker实现linux和windows容器修改WSL默认安装&#xff08;也就是linux子系统&#xff09;目录到其他盘 如何利用在windows上配置docker实现linux和windows容器 wsl的基本命令&#xff1a;参考网页 docker入门到实践&#xff1a;参考网页 官方…

深度学习基础--卷积网络

图像的三个特性指出了专门模型架构的必要性。 首先&#xff0c;图像是高维的&#xff0c;一个用于分类任务的典型图像含有 224224 RGB 值&#xff08;即&#xff0c;150528 个输入维度&#xff09;。在全连接网络中&#xff0c;隐藏层的规模通常超过输入大小&#xff0c;因此&a…

uniapp中使用uni.$emit和uni.$on在vue和nvue页面之间传值但是无法赋值的问题

背景&#xff1a;我们在vue页面和nvue页面之间进行传值可以使用uni.$emit和uni.$onsh事件监听实现&#xff0c;官网描述&#xff1a;uni-app官网 (dcloud.net.cn)https://uniapp.dcloud.net.cn/api/window/communication.html#emit 而且官网上也明确说明了&#xff1a; 一、问…

SLMi33x系列SLMi330HCG-DG具有主动保护功能 兼容光耦的单通道带保护功能的隔离驱动器

SLMi33x系列SLMi330HCG-DG优势和亮点&#xff1a;国内首款带DESAT保护功能并兼容光耦驱动的IGBT/SiC隔离驱动器&#xff0c;5kVrms隔离电压和高达10kV的隔离浪涌电压&#xff0c;CMTI超过100kV/us SLMi330HCG-DG内置快速去饱和(DESAT) 故障检测功能、米勒钳位功能、漏极开路故…

棋牌灯控箱计时计费管理系统软件网关端口设置方法 佳易王麻将馆计时收银会员管理系统操作教程

一、前言 棋牌灯控箱计时计费管理系统软件网关端口设置方法 佳易王麻将馆计时收银会员管理系统操作教程 1、佳易王计时计费软件可接配套的灯控器 2、计时开灯则打开对应的灯 3、结账后自动关灯。 二、软件程序功能图文 1、当前计费方式可以按单价或时间段 2、软件解压即可…

永成分歧式防爆器Y-FBQ型

永成分歧式防爆器Y-FBQ型 当努力成为生活的常态&#xff0c; 生活就时刻充满期待&#xff0c; 深知每份订单都是信任&#xff0c; 品质和专业是我晒单的底气。 用途 型号为Y-FBQ型&#xff0c;分歧式防爆器是安装在瓦斯抽放管路中的简易防爆装置。此款产品主要由进气管、出气…

HarmonyOS开发5.0【rcp网络请求】

一 概述 现在鸿蒙的网络还不成熟&#xff0c;所以咱们需要对网络请求框架二次封装&#xff0c;并且避免业务方直接引用到,预防当有比较新的成熟性价比高的框架的替换&#xff0c;这个过程肯定是不可避免的 1.1 第三方比如 [axios]的js库迁移过来的[httpclient]通过socket&am…

Linux s3c2440 开发板上的操作系统实现 ubuntu

使用s3c2440开发板 使用ubuntu 1.ubuntu中的tftp&#xff0c;和nfs Trivial File Transfer Protocol,简单文件 传输协议。 通过网络在客户端与服务器之间进行简单文件 传输。提供不复杂、开销不大的文件传输服务。 Network File System&#xff0c;网络文件系统。通过 网络…

OpenStack概论和部署

目录 1.1 云计算概述 1.1.1 什么是云计算 1.laaS 2.PaaS 3.Saas 1.1.2 0penStack 概述 1.OpenStack 起源 2.什么是 Openstack 3.OpenStack 优势 1.2 安装方式 1.2.1 在线安装 1.配置系统基本环境 2.为系统设置阿里的仓库 3&#xff1a;设置kvm源 4&#xff1a;设…

【HarmonyOS】头像圆形裁剪功能之手势放大缩小,平移,双击缩放控制(三)

【HarmonyOS】头像裁剪之手势放大缩小&#xff0c;平移&#xff0c;双击缩放控制&#xff08;三&#xff09; 一、DEMO效果图&#xff1a; 二、开发思路&#xff1a; 使用矩阵变换控制图片的放大缩小和平移形态。 通过监听点击手势TapGesture&#xff0c;缩放手势PinchGes…

安泰功率放大器在压电马达中的应用实例

压电马达是一种利用压电效应的装置&#xff0c;通过在压电陶瓷上施加电场&#xff0c;引发其形变从而产生机械振动。在这个领域&#xff0c;功率放大器的应用为提高效率、精准控制和创新性应用提供了可能。下面将深入介绍功率放大器在压电马达中的实际应用例子。 压电效应是指在…

三维数字图像相关法(3D-DIC)用于复合材料力学性能测试

三维数字图像相关法&#xff08;3D-DIC技术&#xff09;&#xff0c;通过将物体表面随机分布的斑点或伪随机分布的人工散斑场作为变形信息载体&#xff0c;是应用于计算机视觉技术的一种图像测量方法&#xff0c;是一种非接触的&#xff0c;用于全场三维坐标、位移、应变及运动…

微信双开及多开!

在工作中大家可能会在pc端用到一台机器打开多个微信&#xff0c;但是现在windows更新之后&#xff0c;双击就只能打开一个了&#xff0c;以下有两种方式可以微信双开甚至多开。 第一种就是很简单的&#xff1a; ps: taskkill /f /im wechat.exe 这一步的用途就是先清除你电脑…