akw的使用
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是一行一行处理的,从头到尾
'取出根分区的已用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
来个例子
[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]#
[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]#
~是模糊匹配
== 是精确匹配
!~ 是取反的意思
[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指定