目录
一.正则表达式
1.1正则表达式简介
1.2 通配符和元字符
1.3 正则:
1.4 其他
二.awk命令
2.1 awk命令简介
2.2 举例
2.3 分隔符
2.4NF和NR
2.5awk的格式
2.6练习
2.7 awk传参问题
2.8 流控
2.9 数组
awk支持正则表达式,并且在匹配的过程中多次使用到正则,所以学习awk之前,我们先了解shell中正则的一些简单使用(其实python中使用正则跟Linux中使用正则的规则都差不多,想详细了解正则表达式,可以查看我之前一篇专门写正则的博客)https://blog.csdn.net/weixin_43880061/article/details/125265593?spm=1001.2014.3001.5502
regular expression --》re 正则表达式,简称正则
正则定义(用在哪里):使用一些特殊符号+字母和数字按照某个正确的规则组成一个公式用来表示某个意思,这就叫正则表达式
有什么用:用来查找,根据正则表达式表达出来的意思,去海量的文本里查找符合这个意思的内容
在哪里用:很多的命令都有查找的功能,有查找功能的命令都能使用正则,vim,sed,awk,grep
简单的正则例子:^wangshuai{3}[0-9]+ 意思是以wagnshuai开头,i出现3次,数字出现1次以上
通配符:在shell里的叫法
* 代表任意个字符
? 代表一个任意字符串(就是只占一位)
元字符(meta character):在正则表达式里的叫法,用来描述其他字符的字符
* 前面的字符出现0次或多次
? 前面的字符出现0次或1次
+ 前面的字符出现1次或多次
^ 表示以什么开头
$ 表示以什么结尾
. 占位符 表示一个除\n之外的任意字符
{n,m} 匹配前一项n到m次
| 或
1.基本正则:元字符比较少,^,$,*,? grep
2.扩展正则:+,{},| egrep == grep -E
grep,匹配模式在行里查找,然后输出,输出匹配模式的行
模式是什么?模式是grep里包含了正则表达式的一个表达式,按照某个模型根据正则表达式去构成一个公式
写正则表达式,就是找共性的特点,找规律
xargs命令:使一列转为一行,还可以将前面命令的输出作为参数传给后面的命令
[root@xieshan 0707]# cat mail.txt
[email protected] fdffaf1212
[email protected] 8989
[email protected] fjdkfj
[root@xieshan 0707]# egrep -o "[0-Z_]+@[0-Z]+.[a-Z]+" mail.txt
[email protected]
[email protected]
[email protected]
[root@xieshan 0707]# egrep -o "[0-Z_]+@[0-Z]+.[a-Z]+" mail.txt |xargs
[email protected] [email protected] [email protected]
awk是一种编程及数据操纵语言,名称来源于创始人的名字缩写
Gawk is the GNU Project's implementation of the AWK programming language.
GNU是什么?
GNU is not unix
GNU 是一个项目,它的宗旨是构建一个不是unix的操作系统
有什么作用?过滤、截取、统计
用在哪里:文本处理(截取和统计)
awk命令工作原理:
与sed一样, 均是一行一行的读取、处理
sed作用于一整行的处理,而awk将一行分成数个字段来处理
awk是依次对每一行进行处理,然后输出
统计每个用户一共充值了多少钱?--》求和,分类统计
[root@master 77]# cat bill.txt
feng 100
feng 200
feng 350
li 200
ma 100000
li 239
li 890
zhang 100
zhang 350
ma 1000
[root@master 77]# awk '{name[$1]+=$2}END{for (i in name) print i,name[i]}' bill.txt
li 1329
feng 650
zhang 450
ma 101000
[root@master 77]#
name[$1]+=$2 拿$1字段做key,让$2做value,如果数组里有key,就累加,如果没有,初始值是0+value
END{for (i in name) print i,name[i]} END是文件里所有的行都处理完了,最后去执行END部分里的命令
for 循环取遍历name数组里的元素(item),i取name数组里的key,输出key和对应的value
字段 field -->一段长文字被分隔符隔开,形成很多段比较短的文字
列 --》column 字段
一列就是一个字段
行 row line 记录 record
一行就是一条记录
awk截取文本时,会按照指定的分隔符去分隔,默认的分隔符是空格,使用- F可以指定分隔符
1.输入分隔符
默认是空白(包括空格和tab键)
-F ":" FS 输入分隔符变量 The input field separator, a space by default. See Fields,above.
2.输出分隔符
默认是空格
OFS="#" out field separater 输出分隔符变量 The output field separator, a space by default.
举例说明:
[root@xieshan 0707]# awk -F ':' '{print $1$3$7}' /etc/passwd|head -5 #没有, 就会紧挨着输出
root0/bin/bash
bin1/sbin/nologin
daemon2/sbin/nologin
adm3/sbin/nologin
lp4/sbin/nologin
[root@xieshan 0707]# awk -F ':' 'OFS="#"{print $1,$3,$7}' /etc/passwd |head -5 #使用 , 就是调用输出分隔符,默认是空格
root#0#/bin/bash
bin#1#/sbin/nologin
daemon#2#/sbin/nologin
adm#3#/sbin/nologin
lp#4#/sbin/nologin
[root@xieshan 0707]# awk -F ':' 'OFS="#"{print $1$3$7}' /etc/passwd |head -5 #如果指定了输出分隔符,但是print后面的变量没有用逗号隔开,那么OFS也不会生效,还是会紧挨着输出
root0/bin/bash
bin1/sbin/nologin
daemon2/sbin/nologin
adm3/sbin/nologin
lp4/sbin/nologin
awk的四个内置变量分别是:FS、OFS、NF、NR
NF The number of fields in the current input record. 表示最后一个字段,$(NF -1) 倒数第2个字段
NR The total number of input records seen so far. 表示行号
FS # 保存或设置字段分隔符,如FS=”:”
OFS # 输出字段分隔符,默认也是空格,可以改为制表符等
$n # 指定分隔的第n个字段,如$1、$3分别表示第1、第3列
$0 # 当前读入的整行文本内容
~ 匹配,与==相比不是精确比较,模糊匹配
!~ 不匹配,不精确比较
== 等于,必须全部相等,精确比较
!= 不等于,精确比较
&& 逻辑与
|| 逻辑或
+ 匹配时表示1个或1个以上
/[0-9][0-9]+/ 两个或两个以上数字
/[0-9][0-9]*/ 一个或一个以上数字
[root@xieshan 0707]# awk -F ':' 'OFS="#"{print $1,$3,$7,$NF}' /etc/passwd|head -5
root#0#/bin/bash#/bin/bash
bin#1#/sbin/nologin#/sbin/nologin
daemon#2#/sbin/nologin#/sbin/nologin
adm#3#/sbin/nologin#/sbin/nologin
lp#4#/sbin/nologin#/sbin/nologin
[root@xieshan 0707]# awk -F ':' 'OFS="#"{print NR,$1,$3,$7}' /etc/passwd|head -5
1#root#0#/bin/bash
2#bin#1#/sbin/nologin
3#daemon#2#/sbin/nologin
4#adm#3#/sbin/nologin
5#lp#4#/sbin/nologin
# 格式1
前置命令 | awk [选项] '条件{编辑指令}'
# 格式2
awk [-F|-f|-v] 'BEGIN{} //{command1; command2} END{}' 文件
[-F|-f|-v] 大参数,-F指定分隔符,-f调用脚本,-v定义变量 var=value
' ' 引用代码块
BEGIN 初始化代码块,在对每一行进行处理之前,初始化代码,主要是引用全局变量,设置FS分隔符
// 匹配代码块,可以是字符串或正则表达式
{} 命令代码块,包含一条或多条命令
; 多条命令使用分号分隔
END 结尾代码块,在对每一行进行处理之后再执行的代码块,主要是进行最终计算或输出结尾摘要信息
# 编辑指令如果包含多条语句时,可以用分号分隔,处理文本时,若未指定分隔符,则默认将空格、制表符等作为分隔符。print是最常见的指令。
[root@xieshan 0707]# awk -F: 'BEGIN{print "######start#####"} $3>500&&$3<1000{print $1,$3}END{print "#####end#####"}' /etc/passwd
######start#####
polkitd 999
chrony 998
zabbix 997
nginx 996
#####end#####
[root@xieshan 0707]# awk -F: 'BEGIN{num=0;print "###start###"} $1~/^feng{2,}/ && $3>2000|| $NF ~ /bash/ {print NR,NF,$1,$3,length($1),$(NF-1),$NF;num++} END{print "行数:"num}' /etc/passwd
###start###
1 7 root 0 4 /root /bin/bash
20 7 sc 1000 2 /home/sc /bin/bash
21 7 sc1 1001 3 /home/sc1 /bin/bash
22 7 ll 1002 2 /home/ll /bin/bash
......省略很多个输出
69 7 sanle 2009 5 /home/sanle /bin/bash
70 7 luodayou 2010 8 /home/luodayou /bin/bash
行数:40
[root@xieshan 0707]#
[root@xieshan 0707]# who|awk '{print "username:"$1" time:"$3}'
username:root time:2022-07-06
username:root time:2022-07-07
username:root time:2022-07-07
username:root time:2022-07-07
[root@xieshan 0707]# awk '{print "username:"$1," uid:"$3}' /etc/passwd|head -5
username:root:x:0:0:root:/root:/bin/bash uid:
username:bin:x:1:1:bin:/bin:/sbin/nologin uid:
username:daemon:x:2:2:daemon:/sbin:/sbin/nologin uid:
username:adm:x:3:4:adm:/var/adm:/sbin/nologin uid:
username:lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin uid:
[root@xieshan 0707]# awk -F: '/bash/{print "username:"$1," uid:"$3}' /etc/passwd|head -5
username:root uid:0
username:sc uid:1000
username:sc1 uid:1001
username:ll uid:1002
username:kim uid:1003
[root@xieshan 0707]# awk -F: '/feng/{print "username:"$1," uid:"$3}' /etc/passwd|head -5
username:califeng uid:1025
[root@xieshan 0707]# awk -F: '$1~/feng/{print "username:"$1," uid:"$3}' /etc/passwd|head -5
username:califeng uid:1025
[root@xieshan 0707]#
[root@xieshan 0707]# awk -F'[:/]' '{print $1,$10}' /etc/passwd|head
root bash
bin nologin
daemon nologin
adm sbin
lp
sync sync
shutdown shutdown
halt halt
mail
operator nologin
[root@xieshan 0707]# vim grade.txt
[root@xieshan 0707]# cat grade.txt
id name chinese math english
1 cali 80 80 80
2 rose 90 98 29
3 tom 89 98 89
4 jenny 100 60 90
[root@xieshan 0707]# awk '{print $2,$3}' grade.txt
name chinese
cali 80
rose 90
tom 89
Jenny 100
[root@xieshan 0707]# vim grade.txt
[root@xieshan 0707]# cat grade.txt
id name chinese math english//linux
1 cali 80 80 80//90
2 rose 90 98 29//99
3 tom 89 98 89//78
4 jenny 100 60 90//77
[root@xieshan 0707]# awk -F'[ /]+' '{print $2,$3,$6}' grade.txt #+表示连续的多个分隔符当成一个分隔符使用,这里的分隔符有空格和/
name chinese linux
cali 80 90
rose 90 99
tom 89 78
jenny 100 77
[root@xieshan 0707]# awk '{gsub("/"," ",$5);print $2,$3,$5}' grade.txt #gsub是把$5的/替换成空格,并且当成一个整体$5
name chinese english linux
cali 80 80 90
rose 90 29 99
tom 89 89 78
jenny 100 90 77
tr命令:字符转换和删除的命令
-s 压缩连续的相同的字符串为同一个字符
-d 删除字符串
[root@xieshan 0707]# cat grade.txt |tr '//' "\t" #将//转换成一个tab键
id name chinese math english linux
1 cali 80 80 80 90
2 rose 90 98 29 99
3 tom 89 98 89 78
4 jenny 100 60 90 77
[root@xieshan 0707]# cat grade.txt |tr -s "/"
id name chinese math english/linux
1 cali 80 80 80/90
2 rose 90 98 29/99
3 tom 89 98 89/78
4 jenny 100 60 90/77
[root@xieshan 0707]# cat grade.txt |tr -s "/ " #压缩连续相同的/或者空格
id name chinese math english/linux
1 cali 80 80 80/90
2 rose 90 98 29/99
3 tom 89 98 89/78
4 jenny 100 60 90/77
[root@xieshan 0707]# cat grade.txt |tr -s "/" " " #将/用空格替换
id name chinese math english linux
1 cali 80 80 80 90
2 rose 90 98 29 99
3 tom 89 98 89 78
4 jenny 100 60 90 77
[root@xieshan 0707]# echo aaaabbbbbbababccab123 |tr ab 89 #将ab替换成89
88889999998989cc89123
[root@xieshan 0707]# awk -F: '$3 ~ /[0-9]{5}/{print $1,$3}' /etc/passwd
nfsnobody 65534
[root@xieshan 0707]# awk -F: '$1 ~ /\/{print $1,$3}' /etc/passwd
luoziyao 2011
输出/etc/passwd里面,uid大于1000,并且shell用的是bash,统计有多少个
[root@xieshan 0707]# awk -F: 'BEGIN{num=0}$7~/bash/&&$3>1000{print $3,$7;num++}END{print "行数:"num}' /etc/passwd
1001 /bin/bash
1002 /bin/bash
......省略很多个输出
2010 /bin/bash
2011 /bin/bash
行数:39
[root@xieshan 0707]#
awk实现输出/etc/passwd的第一行和最后1行
===============未使用awk
[root@xieshan 0707]# head -1 /etc/passwd;tail -1 /etc/passwd
root:x:0:0:root:/root:/bin/bash
luoziyao:x:2011:2011::/home/luoziyao:/bin/bash
===============使用awk
[root@xieshan 0707]# awk 'NR==1{print NR,$0}END{print NR,$0}' /etc/passwd
1 root:x:0:0:root:/root:/bin/bash
71 luoziyao:x:2011:2011::/home/luoziyao:/bin/bash
答案:
1.[root@xieshan 0707]# df -h|awk '{print $1}'
2.[root@xieshan 0707]# awk -F: 'NR==5||NR==10{print NR,$1}' /etc/passwd
3.[root@xieshan 0707]# awk -F: '{print $(NF-1)}' /etc/passwd
4.[root@xieshan 0707]# awk -F: 'NR>=5&&NR<=10 {print $1}' /etc/passwd
5.[root@xieshan 0707]# awk -F: '$7 !~/bash/ {print $1}' /etc/passwd
6.[root@xieshan 0707]# awk -F: 'NR~/.5/ {print NR,$0}' /etc/passwd
[root@xieshan 0707]# awk -F: 'NR~/5$/ {print NR,$0}' /etc/passwd
7.[root@xieshan 0707]# ip a|awk '$1 ~/^inet$/ && $3 ~/brd/ {print $2,$3}'
8.[root@xieshan 0707]# ifconfig ens33|awk -F' ' '$2 ~/packets/ {print $1,$5}'
[root@xieshan 0707]# ifconfig|egrep -A8 "^ens33"|awk '/RX p/ || /TX p/{print $1,$5}'
9.[root@xieshan 0707]# awk -F: 'BEGIN{num=0}$1 ~/^r/ {print $1;num++}END{print "一共有"num"个用户以r开头"}' /etc/passwd
10.[root@xieshan 0707]# watch -n 2 -d "ifconfig|awk 'NR==5{print $5}'"
[root@xieshan 0707]# watch -n 2 -d "ifconfig|egrep -A8 "^ens33"|awk '/RX p/ || /TX p/{print \$5}'"
watch命令:
-n interval seconds 指定间隔时间 -d 高亮显示
11.[root@xieshan 0707]# awk -F: 'BEGIN{print"查找结果:";num=0}$1 ~/^r/ {print $1;num++}END{print "行数:"num}' /etc/passwd
在awk内部调用变量,不需要添加$符号,只有位置变量必须要添加$
在awk中使用,引用的shell变量不需要转义,但是要加$符号,但是位置变量需要转义,注意这里使用双引号
[root@xieshan 0707]# echo $$ #查看当前进程的pid
8184
[root@xieshan 0707]# awk '{print PROCINFO["pid"],PROCINFO["ppid"]}' /etc/passwd #PROCINFO这个数组是awk内置数组,用来存储进程相关信息
[root@xieshan 0707]# sg=renhaodong #shell中定义的变量
[root@xieshan 0707]# useradd renhaodong
[root@xieshan 0707]# awk '/sg/{print $1}' /etc/passwd
[root@xieshan 0707]# awk "/sg/{print $1}" /etc/passwd
[root@xieshan 0707]# awk "/$sg/{print \$1}" /etc/passwd #在awk中使用,引用的shell变量不需要转义,但是要加$符号,但是位置变量需要转义,注意这里使用双引号
renhaodong:x:2012:2012::/home/renhaodong:/bin/bash
流控:following control
if:if(condition )
for
函数:
length 统计长度
split 将一段字符串根据分隔符号,对文本进行分隔,存放到数组里,使用for循环遍历读取数组里的内容
gsub 替换
substr 截取部分字符串
toupper [root@xieshan 0707]# awk -F: '{print toupper($1)}' /etc/passwd
tolower [root@xieshan 0707]# awk -F: '{print tolower($1)}' /etc/passwd
数组:awk里的数组下标从1开始
求和
统计
air -condition ---AC
awk里的for循环格式:
for (i=0;i<10;i++) {print $i;}
for (i in array){print array[i]} -->直接从数组的下标里读一个值,以此类推取完所有的值,遍历
python里字典:key:value
[root@xieshan 0707]# awk -F: '{if ($1 ~/renhaodong/) print "haoge"}' /etc/passwd #单分支
haoge
[root@xieshan 0707]# awk -F: '{if ($1 ~/renhaodong/) print "haoge";else print "dage"}' /etc/passwd #双分支
[root@xieshan 0707]# awk -F: '{if ($1 ~/renhaodong/) print "haoge";else if ($3>5000) print "dageda";else print "dage"}' /etc/passwd #多分支
[root@xieshan 0707]# awk -F: '{if ($3 == 0) print "超级用户";else if ($3>=1&&$3<=999) print "系统用户";else print "普通用户"}' /etc/passwd
[root@xieshan 0707]# awk -F: 'BEGIN{num1=0;num2=0;num3=0}{if ($3 == 0) num1++;else if ($3>=1&&$3<=999) num2++;else num3++}END{print "一共有超级用户:"num1,"一 有系统用户:"num2,"一共有普通用户:"num3}' /etc/passwd
一共有超级用户:1 一共有系统用户:26 一共有普通用户:45
[root@xieshan 0707]# awk -F: '{if ($3 == 0) num1++;else if ($3>=1&&$3<=999) num2++;else num3++}END{print "一共有超级用户:"num1,"一共有系统用户:"num2,"一共有 通用户:"num3}' /etc/passwd #不提前定义也可以
一共有超级用户:1 一共有系统用户:26 一共有普通用户:45
[root@xieshan 0707]# awk -F: 'BEGIN{num1=0;num2=0;num3=0}{if ($3 == 0) {num1++;print "超级用户"}else if ($3>=1&&$3<=999) {num2++;print "系统用户"}else {num3++;print "普通用户"}}END{print "一共有超级用户:"num1,"一共有系统用户:"num2,"一共 普通用户:"num3}' /etc/passwd #多条命令使用花括号,不需要再接分号
[root@xieshan 0707]# awk -F: 'length($1) > 6{print $1}' /etc/passwd
[root@xieshan 0707]# awk -F: '{if (length($1) > 6) print $1}' /etc/passwd
[root@xieshan 0707]# awk -F: '{if (length($1) > 6) print substr($1,1,5)}' /etc/passwd |head -5
split切割:python中和awk一致
>>> mn = "aojiao wangzuxian luoziyao shiyuqian"
>>> mns = mn.split()
>>> mns
['aojiao', 'wangzuxian', 'luoziyao', 'shiyuqian']
>>> sg = "wang/feng/xie/li/zeng/yang"
>>> sg2 = sg.split("/")
>>> sg2
['wang', 'feng', 'xie', 'li', 'zeng', 'yang']
awk里面的数组下标从1开始
[root@xieshan 0707]# awk -F: '{split($6,home_dir,"/")}END{for (i in home_dir)print i,home_dir[i]}' /etc/passwd
[root@xieshan 0707]# awk -F: '{split($6,home_dir,"/");for (i in home_dir)print i,home_dir[i]}' /etc/passwd
[root@xieshan 0707]# awk -F: '{split($6,home_dir,"/");for (i=2;i<4;i++)print i,home_dir[i]}' /etc/passwd
根据一个文件里的内容,批量新建用户和设置密码:
[root@xieshan 0707]# awk '{system("useradd " $1)}' name.txt #调用shell命令
方法一:
[root@xieshan 0707]# awk '{system("useradd "$1);system("echo "$2"| passwd "$1" --stdin")}' name.txt
方法二:
[root@xieshan 0707]# cat adduser.sh
#!/bin/bash
while read user pwd
do
useradd $user
echo $pwd|passwd $user --stdin
done < name.txt
方法三:
[root@xieshan 0707]# cat useradd_multi.sh
#!/bin/bash
username=($(awk '{print $1}' name.txt)) #成为一个数组
userpwd=($(awk '{print $2}' name.txt)) #也是数组
for i in $(seq $(cat name.txt|wc -l))
do
useradd ${username[i-1]}
echo ${userpwd[i-1]}|passwd ${username[i-1]} --stdin
done
对/etc/passwd的第三列求和:
[root@xieshan 0707]# awk -F: '{sum+=$3}END{print sum}' /etc/passwd
136000
对1-100进行求和:
[root@xieshan 0707]# seq 100|awk '{sum+=$1}END{print sum}'
5050
分类+累加求和
统计相同的ip的流量:
[root@xieshan 0707]# cat ip.txt
172.16.130.26 16274.7
172.16.20.126 8783.61
172.16.130.33 5876.59
173.16.13.145 5389.23
172.16.13.145 5389.23
172.16.13.145 5389.23
172.16.20.126 8783.61
172.16.145.173 4974.36
172.16.13.145 5389.23
173.16.13.145 5389.23
173.16.13.145 5389.23
173.16.13.145 5389.23
[root@xieshan 0707]# awk '{ip[$1]+=$2}END{for (i in ip)print i,ip[i]}' ip.txt|sort -k2 -nr
173.16.13.145 21556.9
172.16.20.126 17567.2
172.16.130.26 16274.7
172.16.13.145 16167.7
172.16.130.33 5876.59
172.16.145.173 4974.36
统计每个人的充值数额,按照升序排序:
[root@xieshan 0707]# cat bill.txt
feng 100
feng 200
feng 350
li 200
ma 100000
li 239
li 890
zhang 100
zhang 350
ma 1000
[root@xieshan 0707]# awk '{bill[$1]+=$2}END{for (i in bill)print i,bill[i]}' bill.txt |sort -k2 -n
zhang 450
feng 650
li 1329
ma 101000
统计各个省份的票数,输出省份和总票数,按照降序排序:
[root@xieshan 0707]# cat a.txt
山东 aa 2
河南 bb 3
江西 cc 3
湖南 aa 40
山东 bb 10
江西 dd 6
河南 cc 3
湖南 cc 3
[root@xieshan 0707]# awk '{a[$1]+=$3}END{for (i in a)print i,a[i]}' a.txt |sort -k2 -nr
湖南 43
山东 12
江西 9
河南 6
使用netstat -anplut命令得到一个文本:
1、统计每个state的数量
2、统计输出连接到本主机连接数最多的3个IP,并按连接数从多到少排序(降序)
3、用IP简单的正则匹配上面出现的所有的IP
[root@xieshan 0707]# cat address.txt
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 172.16.18.227:38734 172.16.10.25:5921 ESTABLISHED
tcp 0 0 172.16.18.227:33046 172.16.17.83:5921 ESTABLISHED
tcp 0 0 127.0.0.1:38978 127.0.0.1:12321 TIME_WAIT
tcp 0 0 127.0.0.1:38990 127.0.0.1:12321 TIME_WAIT
tcp 0 0 127.0.0.1:3306 127.0.0.1:35422 ESTABLISHED
tcp 0 0 127.0.0.1:38912 127.0.0.1:12321 TIME_WAIT
tcp 0 0 172.16.18.227:38734 172.16.10.25:5921 ESTABLISHED
tcp 0 0 172.16.18.227:33046 172.16.17.83:5921 ESTABLISHED
tcp 0 0 127.0.0.1:38978 127.0.0.1:12321 TIME_WAIT
tcp 0 0 127.0.0.1:38990 127.0.0.1:12321 TIME_WAIT
tcp 0 0 127.0.0.1:3306 127.0.0.1:35422 ESTABLISHED
tcp 0 0 127.0.0.1:38912 127.0.0.1:12321 TIME_WAIT
tcp 0 0 127.0.0.1:10248 0.0.0.0:* LISTEN 978/kubelet
tcp 0 0 127.0.0.1:10249 0.0.0.0:* LISTEN 3146/kube-proxy
tcp 0 0 192.168.2.130:2379 0.0.0.0:* LISTEN 2650/etcd
tcp 0 0 127.0.0.1:2379 0.0.0.0:* LISTEN 2650/etcd
1、统计每个state的数量
[root@xieshan 0707]# awk 'NR>1{a[$6]+=1}END{for (i in a)print i,a[i]}' address.txt |sort -k2 -nr
TIME_WAIT 6
ESTABLISHED 6
LISTEN 4
2、统计输出连接到本主机连接数最多的3个IP,并按连接数从多到少排序(降序)
[root@xieshan 0707]# awk '$6=="ESTABLISHED"{a[$5]+=1}END{for (i in a)print i,a[i]}' address.txt |sort -k2 -nr
172.16.17.83:5921 2
172.16.10.25:5921 2
127.0.0.1:35422 2
3、用IP简单的正则匹配上面出现的所有的IP
[root@xieshan 0707]# awk '$4,$5 ~/^((25[0-5]|2[0-4]\d|1?\d\d?)\.){3}(25[0-5]|2[0-4]\d|1?\d\d?)$/{print $4,$5}' address.txt
Local Address
172.16.18.227:38734 172.16.10.25:5921
172.16.18.227:33046 172.16.17.83:5921
127.0.0.1:38978 127.0.0.1:12321
127.0.0.1:38990 127.0.0.1:12321
127.0.0.1:3306 127.0.0.1:35422
127.0.0.1:38912 127.0.0.1:12321
172.16.18.227:38734 172.16.10.25:5921
172.16.18.227:33046 172.16.17.83:5921
127.0.0.1:38978 127.0.0.1:12321
127.0.0.1:38990 127.0.0.1:12321
127.0.0.1:3306 127.0.0.1:35422
127.0.0.1:38912 127.0.0.1:12321
127.0.0.1:10248 0.0.0.0:*
127.0.0.1:10249 0.0.0.0:*
192.168.2.130:2379 0.0.0.0:*
127.0.0.1:2379 0.0.0.0:*
有一个nginx的日志文件:
1.计算每分钟的带宽
2.统计每个URI(即不带问号?后面的内容)的每分钟的频率
[root@xieshan 0707]# cat nginx.log
##以下是nginx日志的字段含义
##$time_iso8601|$host|$http_cf_connecting_ip|$request|$status|$body_bytes_sent|$http_referer|$http_user_agent
2019-04-25T09:51:58+08:00|a.google.com|47.52.197.27|GET /v2/depth?symbol=aaa HTTP/1.1|200|24|-|apple
2019-04-25T09:52:58+08:00|b.google.com|47.75.159.123|GET /v2/depth?symbol=bbb HTTP/1.1|200|407|-|python-requests/2.20.0
2019-04-25T09:54:58+08:00|d.shuzibi.co|-||HEAD /justfor.txt HTTP/1.0|200|0|-|-
2019-04-25T09:55:58+08:00|e.google.com|13.251.98.2|GET /v2/order_detail?apiKey=ddd HTTP/1.1|200|231|-|python-requests/2.18.4
2019-04-25T09:56:58+08:00|f.google.com|210.3.168.106|GET /v2/trade_detail?apiKey=eee HTTP/1.1|200|24|-|-
2019-04-25T09:57:58+08:00|g.google.com|47.75.115.217|GET /v2/depth?symbol=fff HTTP/1.1|200|397|-|python-requests/2.18.4
2019-04-25T09:58:58+08:00|h.google.com|47.75.58.56|GET /v2/depth?symbol=ggg HTTP/1.1|200|404|-|safari
2019-04-25T09:54:58+08:00|d.shuzibi.co|-||HEAD /justfor.txt HTTP/1.0|200|0|-|-
2019-04-25T09:55:58+08:00|e.google.com|13.251.98.2|GET /v2/order_detail?apiKey=ddd HTTP/1.1|200|231|-|python-requests/2.18.4
2019-04-25T09:56:58+08:00|f.google.com|210.3.168.106|GET /v2/trade_detail?apiKey=eee HTTP/1.1|200|24|-|-
2019-04-25T09:59:58+08:00|i.google.com|188.40.137.175|GET /v2/trade_detail?symbol=hhh HTTP/1.1|200|6644|-|-
2019-04-25T09:59:58+08:00|i.google.com|188.40.137.175|GET /v2/trade_detail?symbol=hhh HTTP/1.1|200|6644|-|-
2019-04-25T09:59:58+08:00|i.google.com|188.40.137.175|GET /v2/trade_detail?symbol=hhh HTTP/1.1|200|6644|-|-
2019-04-25T09:59:58+08:00|i.google.com|188.40.137.175|GET /v2/trade_detail?symbol=hhh HTTP/1.1|200|6644|-|-
2019-04-25T10:01:58+08:00|j.google.com|2600:3c01:0:0:f03c:91ff:fe60:49b8|GET /v2/myposition?apiKey=jjj HTTP/1.1|200|110|-|scan
2019-04-25T09:58:58+08:00|h.google.com|47.75.58.56|GET /v2/depth?symbol=ggg HTTP/1.1|200|404|-|safari
2019-04-25T09:59:58+08:00|i.google.com|188.40.137.175|GET /v2/trade_detail?symbol=hhh HTTP/1.1|200|6644|-|-
2019-04-25T10:01:58+08:00|j.google.com|2600:3c01:0:0:f03c:91ff:fe60:49b8|GET /v2/myposition?apiKey=jjj HTTP/1.1|200|110|-|scan
计算每分钟的带宽
用时间做key,body_bytes_sent做value,进行累计
[root@xieshan 0707]# awk -F"|" '{traffic[substr($1,1,16)]+=$6}END{for (i in traffic) print i,traffic[i]}' nginx.log|sort -k2 -nr|head -5
2019-04-25T09:59 33220
2019-04-25T09:58 808
2019-04-25T09:55 462
2019-04-25T09:52 407
2019-04-25T09:54 400
统计每个URI(即不带问号?后面的内容)的每分钟的频率
以时间+uri作为key值,出现次数作为value
[root@xieshan 0707]# awk -F"[ |?]+" '{uri[substr($1,1,16)$5]+=1}END{for (i in uri)print i,uri[i]}' nginx.log |sort -k2 -nr|head -3
2019-04-25T09:59/v2/trade_detail 5
2019-04-25T10:01/v2/myposition 2
2019-04-25T09:58/v2/depth 2
awk可以对日志文件进行分析
数据采集/收集--》清洗数据--》数据集--》数据仓库---》数据分析
##########################
求取grade.txt中,每科成绩中分数最高的人和它的姓名
[root@xieshan lianxi]# vim grade.txt
[root@xieshan lianxi]# cat grade.txt
学生A 语文 100
学生B 数学 90
学生A 英语 99
学生C 语文 80
学生B 英语 56
[root@xieshan lianxi]# awk '{if (a[$2]<$3) {a[$2]=$3;b[$2]=$1}}END{for (i in a)print "科目:"i,"分数:"a[i],"姓名:"b[i]}' grade.txt
科目:语文 分数:100 姓名:学生A
科目:数学 分数:90 姓名:学生B
科目:英语 分数:99 姓名:学生A
在上面这个例子中,a[$2]代表的其实是分数,b[$2]代表的是姓名,这都是自己定义的;可以理解为$2--->a[$2]以及$2--->b[$2]