shell编程-5

akw的使用

  • shell学习第五天
    • 1.时间的正则
    • 简单使用awk
    • 深入学习 awk
      • akw的完整语法
      • 来个例子
      • 内置变量
      • 复杂的例子
    • 练习
      • 查找出 /etc/passwd文件里的用户名包含a字符串的用户名,并且输出用户名,统计有多少个这样的用户
    • 小知识点
      • time命令
      • 分隔符分两种

shell学习第五天

1.时间的正则

2024年1月1号到1月31号的正则

[root@gh-shell 1-19] cat access.log |egrep "([1-9]|[12][0-9]|3[01])/Jan/2024"

2024年1月19日 9点到21点之间的日志

[root@gh-shell 1-19] cat access.log |egrep  "19/Jan/2024:(09|1[0-9]|2[01]):(0[1-9]|[1-5][0-9]):([0-5][0-9])"

计算19/Jan/2024:09:01~59 分钟每分钟的流量

[root@gh-shell 1-19] cat access.log |egrep "19/Jan/2024:09:(0[1-9]|[1-5][0-9]):([0-5][0-9])"
'01-59的正则'
0[1-9]|[1-5][0-9]
'00~59秒的正则'
19/Jan/2024:09:(0[1-9]|[1-5][0-9]):([0-5][0-9])

计算19/Jan/2024:00:00~23:59 分钟每分钟的流量

这个实现得需要循环去实现

00点

​ 01~59分

01点

​ 01~59分

02点

​ 01~59分

.

.

.

#!/bin/bash

for i in {00..23}
do
	for y in {00..59}
	do
		cat /root/access.log |egrep "19/Jan/2024:$i:$y:[0-5][0-9]"|awk -v i=$i -v y=$y 'BEGIN{print i,y}{sum+=$10}END{print sum}' &>>/root/daikuan.txt
    done
done

简单使用awk

[root@gh-shell 1-19] cat grade.txt 
name	chinese	math	english
cali	80	91	82
tom		90	80	99
lucy	99	70	75
jack	60	89	99
[root@gh-shell 1-19] awk 'NR>1{print $0}' grade.txt 
cali	80	91	82
tom		90	80	99
lucy	99	70	75
jack	60	89	99
[root@gh-shell 1-19]# 

NR是行号—>处理文本的时候的行号 number of record

sum是定义的一个变量,用来进行求和,累加

END是所有的行都处理完了,再把sum的值打印出来,这个时候就是求和的总值

[root@gh-shell 1-19] awk 'NR>1{sum += $3}END{print sum}' grade.txt 
330
[root@gh-shell 1-19] awk '{print $3}' grade.txt |xargs |tr " " "+"|bc
330
[root@gh-shell 1-19]# 

这让我们们想起了 cut 命令

-c 是对字符的操作

-f 是对列的

-d 是 指定分隔符 默认是 tab作为分隔符

[root@gh-shell 1-19] cat grade.txt | cut -f 1
name
cali
tom
lucy
jack
[root@gh-shell 1-19] echo "asfasdgdfghehh"|cut -c 1-5
asfas
[root@gh-shell 1-19]# 
[root@gh-shell 1-19] cat grade.txt | cut -f 1,2
name	chinese
cali	80
tom	90
lucy	99
jack	60
[root@gh-shell 1-19]# 
[root@gh-shell 1-19] cat /etc/passwd|cut -d ":" -f 1 

深入学习 awk

awk:一种编程及数据操作语言(其名称来自于创始人 Alfred Aho、Peter Weinberger 和 Brian Kernighan 姓氏的首字母)

awk是一行一行处理的,从头到尾

shell编程-5_第1张图片

'取出根分区的已用5%'
[root@gh-shell 1-19] df
文件系统                   1K-块    已用     可用 已用% 挂载点
devtmpfs                  919504       0   919504    0% /dev
tmpfs                     931512       0   931512    0% /dev/shm
tmpfs                     931512    9804   921708    2% /run
tmpfs                     931512       0   931512    0% /sys/fs/cgroup
/dev/mapper/centos-root 52403200 2131168 50272032    5% /
/dev/sda1                1038336  153668   884668   15% /boot
/dev/mapper/centos-home 49250820   33404 49217416    1% /home
tmpfs                     186304       0   186304    0% /run/user/0
[root@gh-shell 1-19] df|awk '{print $5}'|head -6|tail -1
5%
[root@gh-shell 1-19]# 
[root@gh-shell 1-19] df|awk '/\/$/{print $5}' # 查找以斜杆结尾的
5%

akw的完整语法

awk 'BEGIN{commands}pattern{commands}END{commands}' file1

shell编程-5_第2张图片

shell编程-5_第3张图片

来个例子

[root@gh-shell 1-19] awk 'BEGIN{print "阿里舅舅股东集资"}{sum += $2}END{print sum}' alijiujiu.txt 
阿里舅舅股东集资
113
[root@gh-shell 1-19] cat alijiujiu.txt 
gaohui	1
gaofei	1
feifei	10
gaoxu	1
dingj   100
[root@gh-shell 1-19]# 
[root@gh-shell 1-19] awk 'BEGIN{print "阿里舅舅股东集资"}{sum += $2;print $0}END{print "阿里舅舅公 司股东集资总金额:"sum}' alijiujiu.txt 
阿里舅舅股东集资
gaohui	1
gaofei	1
feifei	10
gaoxu	1
dingj   100
阿里舅舅公司股东集资总金额:113
[root@gh-shell 1-19]# 
[root@gh-shell 1-19] awk 'BEGIN{print "阿里舅舅股东集资"}{sum += $2;print $0}END{print "阿里舅舅公 司股东集资总金额:"sum "元"}' alijiujiu.txt 
阿里舅舅股东集资
gaohui	1
gaofei	1
feifei	10
gaoxu	1
dingj   100
阿里舅舅公司股东集资总金额:113元
[root@gh-shell 1-19]# 
[root@gh-shell 1-19] awk 'BEGIN{print "阿里舅舅股东集资"}{sum += $2;if ($2>=2) print $0}END{print 阿里舅舅公司股东集资总金额:"sum "元"}' alijiujiu.txt 
阿里舅舅股东集资
feifei	10
dingj   100
阿里舅舅公司股东集资总金额:113元
[root@gh-shell 1-19]# 

[root@gh-shell 1-19] awk 'BEGIN{print "阿里舅舅股东集资"} $2>=2 {sum += $2;print $0}END{print "阿.舅舅公司股东集资总金额:"sum "元"}' alijiujiu.txt 
阿里舅舅股东集资
feifei	10
dingj   100
阿里舅舅公司股东集资总金额:110元
[root@gh-shell 1-19]# 
[root@gh-shell 1-19] cat /etc/passwd|awk -F: 'BEGIN{print "####start####"}$3>500&&$3<1000{print $1,$3}END{print "@@@@end@@@@"}'
####start####
polkitd 999
chrony 998
@@@@end@@@@
[root@gh-shell 1-19]# 

匹配/etc/passwd里边sc1开头的用户

[root@gh-shell 1-19] awk -F: 'BEGIN{print "start"} $1 ~ /sc1/{print $1} END{print "end"}' /etc/passwd
start
sc1
sc10
sc11
sc12
sc13
sc14
sc15
sc16
sc17
sc18
sc19
end
[root@gh-shell 1-19]# 

统计总数

[root@gh-shell 1-19] awk -F: 'BEGIN{print "start";i=0} $1 ~ /sc1/{print $1;i += 1} END{print "end";print "以sc1开头的用户总共有:"i "个"}' /etc/passwd
start
sc1
sc10
sc11
sc12
sc13
sc14
sc15
sc16
sc17
sc18
sc19
end
以sc1开头的用户总共有:11个
[root@gh-shell 1-19]# 
[root@gh-shell 1-19] awk -F: 'BEGIN{print "start";i=0} $1 ~ /sc1/{print $1;i += 1} END{print "end", "以sc1开头的用户总共有:"i "个"}' /etc/passwd
start
sc1
sc10
sc11
sc12
sc13
sc14
sc15
sc16
sc17
sc18
sc19
end 以sc1开头的用户总共有:11个
[root@gh-shell 1-19]# 

内置变量

NR–>行号 number of record 记录的编号,一行就是一条记录

NF–>每行的字段数 一行有多少列

FS–>输入分隔符

PFS—>输出分隔符

复杂的例子

统计 /etc/passwd 文件中用户名为 “sc1” 或用户ID大于1005的行数,并打印了这些行的详细信息:

length() 统计长度的函数 —> 工具 awk自带

$NF 表示最后一个字段

$(NF-1) 表示倒数第二个字段

[root@gh-shell 1-19] cat /etc/passwd|awk -F: 'BEGIN{num=0;print "开始统计/etc/passwd文件"} $1 ~/sc1/ || $3 > 1005 {print NR,NF,$1,length($1),$(NF-1),$NF,$3;num++}END{print "统计结束",num}'
开始统计/etc/passwd文件
21 7 sc1 3 /home/sc1 /bin/bash 1000
27 7 sc7 3 /home/sc7 /bin/bash 1006
28 7 sc8 3 /home/sc8 /bin/bash 1007
29 7 sc9 3 /home/sc9 /bin/bash 1008
30 7 sc10 4 /home/sc10 /bin/bash 1009
31 7 sc11 4 /home/sc11 /bin/bash 1010
32 7 sc12 4 /home/sc12 /bin/bash 1011
33 7 sc13 4 /home/sc13 /bin/bash 1012
34 7 sc14 4 /home/sc14 /bin/bash 1013
35 7 sc15 4 /home/sc15 /bin/bash 1014
36 7 sc16 4 /home/sc16 /bin/bash 1015
37 7 sc17 4 /home/sc17 /bin/bash 1016
38 7 sc18 4 /home/sc18 /bin/bash 1017
39 7 sc19 4 /home/sc19 /bin/bash 1018
40 7 sc20 4 /home/sc20 /bin/bash 1019
41 7 root1 5 /home/root1 /bin/bash 1020
42 7 root2 5 /home/root2 /bin/root 1021
43 7 liu 3 /home/liu /bin/bash 1022
44 7 liu1 4 /home/liu1 /bin/bash 1023
45 7 liu2 4 /home/liu2 /bin/bash 1024
46 7 liu3 4 /home/liu3 /bin/bash 1025
统计结束 21
[root@gh-shell 1-19]# 

'指定一个输出分隔符,输出行号和倒数第二行'
[root@gh-shell 1-19]df|awk 'OFS="#" {print NR,$(NF-1)}'
1#已用%
2#0%
3#0%
4#2%
5#0%
6#5%
7#15%
8#1%
9#0%
[root@gh-shell 1-19]# 

统计一下 /etc/passwd 名字长度超过10的

[root@gh-shell 1-19] cat /etc/passwd|awk -F: 'length($1) > 10 {print $0}'
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
gaodingjiang:x:1026:1026::/home/gaodingjiang:/bin/bash
gaodingjiang1:x:1027:1027::/home/gaodingjiang1:/bin/bash
gaodingjiang12:x:1028:1028::/home/gaodingjiang12:/bin/bash
gaodingjiang123:x:1029:1029::/home/gaodingjiang123:/bin/bash
[root@gh-shell 1-19]# 

shell编程-5_第4张图片

[root@gh-shell 1-19] awk -F[:/] '/^g/{print $1,$10}' /etc/passwd
games sbin
gaodingjiang bin
gaodingjiang1 bin
gaodingjiang12 bin
gaodingjiang123 bin
[root@gh-shell 1-19]# 

shell编程-5_第5张图片

shell编程-5_第6张图片

~是模糊匹配

== 是精确匹配

!~ 是取反的意思

[root@gh-shell 1-19] awk -F: '$1 == "gaodingjiang"{print $1,$3}' /etc/passwd
gaodingjiang 1026
[root@gh-shell 1-19] awk -F: '$1 ~ /gaodingjiang/{print $1,$3}' /etc/passwd
gaodingjiang 1026
gaodingjiang1 1027
gaodingjiang12 1028
gaodingjiang123 1029
[root@gh-shell 1-19]# 
[root@gh-shell 1-19] awk -F: '$1 !~ /gaodingjiang/{print $1,$3}' /etc/passwd
[root@gh-shell 1-19] awk -F: '$3 ~ /\<...\>/ {print $1,$3}' /etc/passwd
systemd-network 192
polkitd 999
chrony 998
[root@gh-shell 1-19] awk -F: 'length($3) == 3 {print $1,$3}' /etc/passwd
systemd-network 192
polkitd 999
chrony 998
[root@gh-shell 1-19]# 

练习

查找出 /etc/passwd文件里的用户名包含a字符串的用户名,并且输出用户名,统计有多少个这样的用户

[root@gh-shell 1-19] cat /etc/passwd|awk -F: 'BEGIN{num=0} $1 ~ /a/ {print $1;num++} END{print "一 共有"num"个包含a的用户"}'
daemon
adm
halt
mail
operator
games
gaodingjiang
gaodingjiang1
gaodingjiang12
gaodingjiang123
一共有10个包含a的用户
[root@gh-shell 1-19]# 

小知识点

time命令

time命令可以知道一条命令执行的时间

[root@gh-shell 1-19] time cat /etc/passwd|egrep "^root"
root:x:0:0:root:/root:/bin/bash
root1:x:1020:1020::/home/root1:/bin/bash
root2:x:1021:1021::/home/root2:/bin/root

real	0m0.002s
user	0m0.001s
sys	0m0.002s

[root@gh-shell 1-19] time egrep "^root" /etc/passwd
root:x:0:0:root:/root:/bin/bash
root1:x:1020:1020::/home/root1:/bin/bash
root2:x:1021:1021::/home/root2:/bin/root

real	0m0.002s
user	0m0.002s
sys	0m0.000s
[root@gh-shell 1-19]# 

分隔符分两种

1.输入分隔符:默认是空白

-F指定

2.输出分隔符:默认是一个空格

OFS指定

你可能感兴趣的:(shell,服务器,linux,运维)