01.知识概述部分
1)三剑客awk命令概述介绍
2)三剑客awk命令执行原理 语法结构
3)三剑客awk命令实操练习
查询 替换信息 排除(取反)
4)三剑客awk命令高级功能 数组
统计分析数据信息 求和运算/累加运算
02.知识回顾说明
1) 三剑客sed命令语法结构
sed [参数] ‘条件 指令’ 文件信息
2) 三剑客sed命令使用方法
参数信息: -n -i -r -e
指令信息: p d a i s g r? c?
条件信息: $ n n,m /字符/ \n
03.三剑客awk命令概述介绍
awk是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入(stdin)、一个或多个文件,或其它命令的输出。它支持用户自定义函数和动态正则表达式等先进功能,是linux/unix下的一个强大编程工具。它在命令行中使用,但更多是作为脚本来使用。awk有很多内建的功能,比如数组、函数等,这是它和C语言的相同之处,灵活性是awk最大的优势。
awk - pattern scanning and processing language
模式扫描(处理文件每一行信息)过程语言(一门脚本语言 逻辑语句【循环/判断】)
脚本格式:#!/bin/awk
作用说明:
1)擅长对文件列进行操作
2)擅长统计分析数据信息
04.三剑客awk命令执行原理:
执行原理过程:参见示意图
命令语法结构:awk 【参数】'模式信息(条件) {动作信息(指令)} ’ 文件信息
awk相关参数:
-F fs fs指定输入分隔符,fs可以是字符串或正则表达式,如-F:
-v var=value 赋值一个用户定义变量,将外部变量传递给awk
-f scripfile 从脚本文件中读取awk命令
awk内置变量(预定义变量)
说明:[A][N][P][G]表示第一个支持变量的工具,[A]=awk、[N]=nawk、[P]=POSIXawk、[G]=gawk
$n 当前记录的第n个字段,比如n为1表示第一个字段,n为2表示第二个字段。
$0 这个变量包含执行过程中当前行的文本内容。
[N] ARGC 命令行参数的数目。
[G] ARGIND 命令行中当前文件的位置(从0开始算)。
[N] ARGV 包含命令行参数的数组。
[G] CONVFMT 数字转换格式(默认值为%.6g)。
[P] ENVIRON 环境变量关联数组。
[N] ERRNO 最后一个系统错误的描述。
[G] FIELDWIDTHS 字段宽度列表(用空格键分隔)。
[A] FILENAME 当前输入文件的名。
[P] FNR 同NR,但相对于当前文件。
[A] FS 字段分隔符(默认是任何空格)。
[G] IGNORECASE 如果为真,则进行忽略大小写的匹配。
[A] NF 表示字段数,在执行过程中对应于当前的字段数。
[A] NR 表示记录数,在执行过程中对应于当前的行号。
[A] OFMT 数字的输出格式(默认值是%.6g)。
[A] OFS 输出字段分隔符(默认值是一个空格)。
[A] ORS 输出记录分隔符(默认值是一个换行符)。
[A] RS 记录分隔符(默认是一个换行符)。
[N] RSTART 由match函数所匹配的字符串的第一个位置。
[N] RLENGTH 由match函数所匹配的字符串的长度。
[N] SUBSEP 数组下标分隔符(默认值是34)。
05.三剑客awk命令操作练习
cat xxx|column -t 按照表格对齐 >> xxx文件
准备环境:
# cat >> awk_test.txt <<EOF
Zhang Dandan 41117397 :250:100:175
Zhang Xiaoyu 390320151 :155:90:201
Meng Feixue 80042789 :250:60:50
Wu Waiwai 70271111 :250:80:75
Liu Bingbing 41117483 :250:100:175
Wang Xiaoai 3515064655 :50:95:135
Zi Gege 1986787350 :250:168:200
Li Youjiu 918391635 :175:75:300
Lao Nanhai 918391635 :250:100:175
EOF
建个文本尝试排除文件tab内容
sed 's#\t##g' 文件名
练习题:
取出多列内容:
[root@jason oldboy 20:17:20]# awk '{for(i=1;i<=3;i++)printf $i""FS;print""}' awk_test.txt
Zhang Dandan 41117397
Zhang Xiaoyu 390320151
Meng Feixue 80042789
Wu Waiwai 70271111
Liu Bingbing 41117483
Wang Xiaoai 3515064655
Zi Gege 1986787350
Li Youjiu 918391635
Lao Nanhai 918391635
1)显示Xiaoyu的姓氏和ID号码
答案一:
解题步骤一:根据条件找出相应行
awk '/Xiaoyu/{print $0}' ($0代表将这一行所有内容输出来)
[root@jason oldboy 10:08:23]# awk '/Xiaoyu/{print $0}' awk_test.txt
Zhang Xiaoyu 390320151 :155:90:201
[root@jason oldboy 10:12:31]# awk '/Xiaoyu/' awk_test.txt
Zhang Xiaoyu 390320151 :155:90:201
解题步骤二:输出相应列信息
[root@jason oldboy 10:13:44]# awk '/Xiaoyu/{print $1,$3}' awk_test.txt
Zhang 390320151
[root@jason oldboy 10:13:51]# awk '/Xiaoyu/{print $1" "$3}' awk_test.txt
Zhang 390320151
PS:在系统中有时需要嵌入式使用时,不能使用相同的引号
’ ’ ’ ’ ----错误
" " " " ----错误
’ " " ’ ----正确
" ’ ’ " ----正确
说明:$n~/xxx/ 取出第n列里面有xxx信息
[root@jason oldboy 10:28:34]# awk '$2~/Xiaoai/{print $1,$2,$4}' awk_test.txt
Wang Xiaoai :50:95:135
答案二:
可以根据行号信息进行处理(适合行数少)
思路1)将xiaoyu信息进行匹配 内置变量NR表示行号
[root@jason oldboy]# awk 'NR==2' awk_test.txt 内置变量NR==2代表查找第二行
Zhang Xiaoyu 390320151 :155:90:201
思路2) 根据需求进行处理
awk 'NR==2' /oldboy/awk_test.txt
执行过程:
[root@jason oldboy]# awk 'NR==2{print $1 $3}' awk_test.txt
Zhang390320151 连起来了不好识别
正确:
[root@jason oldboy]# awk 'NR==2{print $1,$3}' awk_test.txt
Zhang 390320151
[root@jason oldboy]# awk 'NR==2{print $1" "$3}' awk_test.txt
Zhang 390320151
说明: awk取出多列信息可以使用 , 或者 " " 进行分隔
2)姓氏是zhang的人,显示他的第二次捐款金额及他的名字
解题步骤一:根据条件找出相应行
[root@jason oldboy]# awk '$1~/Zhang/' awk_test.txt
Zhang Dandan 41117397 :250:100:175
Zhang Xiaoyu 390320151 :155:90:201
解题步骤二:输出相应列信息
示例:
[root@oldboy69 oldboy 10:43:46]# awk -F ":" '{print $2,$3}' test08.txt|column -t
linux 69
linux 66
python 20
dba 01
说明: 利用-F指定列分隔符
[root@oldboy69 oldboy 10:49:50]# awk -F ":|;|@" '{print $2,$3}' test08.txt|column -t
linux 69
linux 66
python 20
dba 01
[root@oldboy69 oldboy 10:49:52]# awk -F " [:;@]" '{print $2,$3}' test08.txt|column -t
linux 69
linux 66
python 20
dba 01
说明: 利用-F指定列分隔符, 结合正则可以识别多个分隔符号
[root@oldboy69 oldboy 10:54:13]# awk -F "[ :@]+" '{print $2,$3}' test08.txt|column -t
linux 69
linux 66
python 20
dba 01
说明: 利用-F指定列分隔符. 可以使用[ :@]+将多个连续分隔符看成一个整体
解题步骤三:
[root@jason oldboy 10:36:50]# awk -F "[ :]+" '$1~/Zhang/{print $1,$2,$5}' awk_test.txt
Zhang Dandan 100
Zhang Xiaoyu 90
3) 显示所有以41开头的ID号码的人的全名和ID号码
解题步骤一: 根据条件找出相应行
awk '$3~/^41/' awk_test.txt
解题步骤二: 输出相应列信息
[root@jason oldboy 20:26:55]# awk '$3~/^41/{print $1,$2,$3}' awk_test.txt
Zhang Dandan 41117397
Liu Bingbing 41117483
4)显示所有以5或者0结尾id显示出来, 并显示人的名字和ID号码
解题步骤一: 根据条件找出相应行
[root@jason oldboy 20:34:59]# awk '$3~/[50]$/' awk_test.txt
Wang Xiaoai 3515064655 :50:95:135
Zi Gege 1986787350 :250:168:200
Li Youjiu 918391635 :175:75:300
Lao Nanhai 918391635 :250:100:175
解题步骤二: 输出相应列信息
[root@jason oldboy 20:32:09]# awk '$3~/[50]$/{print $1,$2,$3}' awk_test.txt
Wang Xiaoai 3515064655
Zi Gege 1986787350
Li Youjiu 918391635
Lao Nanhai 918391635
不要显示以5或者0结尾id, 显示其他id信息名字和ID号码
[root@oldboy69 oldboy 12:05:03]# awk '$3~/[^50]$/{print $1,$2,$3}' awk.txt
Zhang Dandan 41117397
Zhang Xiaoyu 390320151
Meng Feixue 80042789
Wu Waiwai 70271111
Liu Bingbing 41117483
[root@oldboy69 oldboy 12:05:17]# awk '$3!~/[50]$/{print $1,$2,$3}' awk.txt
Zhang Dandan 41117397
Zhang Xiaoyu 390320151
Meng Feixue 80042789
Wu Waiwai 70271111
Liu Bingbing 41117483
说明: !~ 表示进行取反匹配
显示所有ID号码最后一位数字是1或5的人的全名
有多个单个字符用[ ] 有单词字符串的用|
思路1)找出ID号码以1或者5的号码
awk '$3~/1$|5$/' awk_test.txt
[root@linux67 oldboy]# awk '$3~/1$|5$/' awk_test.txt
Zhang Xiaoyu 390320151 :155:90:201
Wu Waiwai 70271111 :250:80:75
Wang Xiaoai 3515064655 :50:95:135
Li Youjiu 918391635 :175:75:300
Lao Nanhai 918391635 :250:100:175
Lao Nanhai 918391635 :250:100:175 Xiaoyu
[root@linux67 oldboy]# awk '$3~/[15]$/' awk_test.txt
Zhang Xiaoyu 390320151 :155:90:201
Wu Waiwai 70271111 :250:80:75
Wang Xiaoai 3515064655 :50:95:135
Li Youjiu 918391635 :175:75:300
Lao Nanhai 918391635 :250:100:175
Lao Nanhai 918391635 :250:100:175 Xiaoyu
思路2) 显示全名信息
# awk '$3~/[15]$/{print $1,$2}' awk_test.txt
Zhang Xiaoyu
Wu Waiwai
Wang Xiaoai
Li Youjiu
Lao Nanhai
Lao Nanhai
扩展问题:显示所有ID号码最后一位数字不是1或5的人的全名
[root@jason oldboy]# awk '$3~/[^15]$/{print $1,$2}' awk_test.txt |column -t
Zhang Dandan
Meng Feixue
Liu Bingbing
Zi Gege
[root@linux67 oldboy]# awk '$3~/[02346789]$/{print $1,$2}' awk_test.txt(笨方法)
Zhang Dandan
Meng Feixue
Liu Bingbing
Zi Gege
叹号取反时放在~前面
[root@linux67 oldboy]# awk '$3!~/[15]$/{print $1,$2,$3}' awk_test.txt
Zhang Dandan 41117397
Meng Feixue 80042789
Liu Bingbing 41117483
Zi Gege 1986787350
5)显示Xiaoyu的捐款,每个金额都有$开头,如$110$220$330
1:
awk -F "[: ]+" '$2~/Xiaoyu/{print "$"$4,"$"$5,"$"$6}' awk_test.txt(太麻烦)
2:
awk '$2~/Xiaoyu/{print $4}' awk_test.txt |sed 's#:#$#g'(还可以)
$155$90$201
awk '$2~/Xiaoyu/{print $4}' awk_test.txt |tr ':' '$'(方便)
[root@jason oldboy]# awk '$2~/Xiaoyu/{print $4}' awk_test.txt |tr ":" "$"
$155$90$201
3:awk替换信息方法
:gsub(/替换的信息/,"要替换成什么",$n替换的第几列信息)
awk '$2~/Xiaoyu/{gsub(/:/,"$",$4);print $4}' awk.txt
$155$90$201
print: 输出指定的信息
gsub:替换指定的信息 gawk substitute --gsub
awk利用gsub替换详解:
格式:gsub(//,"",$x) --> gsub(/要替换的信息/,"替换成的信息"$第几列信息做替换)
gsub(/:/,"$",)
awk '$2~/Xiaoyu/{gsub(/:/,"$",$NF);print $NF}' awk_test.txt
$155$90$201
说明:NF表示列信息,$NF:表示最后一列, 倒数第二列如何表示:正着数== $3
倒着数$NF == $4 -1 一定要加小括号$(4-1)
oldboy linux edu 50
$(NF-1) ($NF)
$(4-1) $4
如果不加,结果就是$4==$NF==50 $NF-1==50-1=49(错误)
06.三剑客awk命令高级用法
1)awk模式概念:
普通模式:利用正则进行匹配/利用行号进行匹配/利用字符进行匹配
匹配条件信息
a根据正则信息进行匹配:^$之类的
b根据范围信息进行匹配 用法多样化
如果有大于><小于范围需要用&&,2到4就用,逗号,2和4用||或;
匹配连续多行
[root@linux67 oldboy]# cat test.txt
01 oldboy python
02 oldboy ptone
03 oldboy path
04 oldboy ptzh
05 oldboy ptzh
06 oldboy ptzh
07 oldboy ptzh
[root@linux67 oldboy]# awk 'NR>2' test.txt
03 oldboy path
04 oldboy ptzh
05 oldboy ptzh
06 oldboy ptzh
07 oldboy ptzh
[root@linux67 oldboy]# awk 'NR<5' test.txt
01 oldboy python
02 oldboy ptone
03 oldboy path
04 oldboy ptzh
[root@linux67 oldboy]# awk 'NR>2 && NR<5' test.txt &&代表和
03 oldboy path
04 oldboy ptzh
[root@linux67 oldboy]# awk 'NR==2,NR==5' test.txt
02 oldboy ptone
03 oldboy path
04 oldboy ptzh
05 oldboy ptzh
匹配不连续多行
[root@linux67 oldboy]# awk 'NR==2||NR==5||NR==7' test.txt
02 oldboy ptone
05 oldboy ptzh
07 oldboy ptzh
[root@linux67 oldboy]# awk 'NR==2;NR==5;NR==7' test.txt
02 oldboy ptone
05 oldboy ptzh
07 oldboy ptzh
匹配不连续多行 ; || 都可以使用
特殊模式:
BEGIN:在处理文件之前先做的事情(准备工作)
1) 将awk作为计算器使用
[root@oldboy69 oldboy 12:26:21]# awk 'BEGIN{print 2+2}'
4
[root@oldboy69 oldboy 12:27:41]# awk 'BEGIN{print 2-2}'
0
[root@oldboy69 oldboy 12:27:44]# awk 'BEGIN{print 2*2}'
4
[root@oldboy69 oldboy 12:27:47]# awk 'BEGIN{print 2/2}'
1
[root@oldboy69 oldboy 12:27:51]# awk 'BEGIN{print 2^2}'
4
[root@oldboy69 oldboy 12:27:57]# awk 'BEGIN{print 2^3}'
8
[root@oldboy69 oldboy 12:28:00]# awk 'BEGIN{print 5%3}'
2.
2) 进行变量设定
awk 'BEGIN{old="oldboy";print old}'
oldboy
awk 'BEGIN{FS=":"}{print $2}' test12.txt
02
awk -vFS=":" '{print $2}' test12.txt
02
内置变量:
NR : 表示行号信息
NF : 表示字段信息(列)
FS : 表示分隔符字段信息
-v 进入变量模式 可以进行变量的赋值及调用(调用不需要加$符)
END :在处理文件之后要做的事情(后续工作)
1)输出结果信息
[root@jason oldboy 20:47:33]# awk 'BEGIN{print "姓","名","id","金额"}{print $0}END{print "老男孩员工捐款记录表"}' awk_test.txt|column -t
姓 名 id 金额
Zhang Dandan 41117397 :250:100:175
Zhang Xiaoyu 390320151 :155:90:201
Meng Feixue 80042789 :250:60:50
Wu Waiwai 70271111 :250:80:75 Xiaoai
Liu Bingbing 41117483 :250:100:175
Wang Xiaoai 3515064655 :50:95:135
Zi Gege 1986787350 :250:168:200
Li Youjiu 918391635 :175:75:300
Lao Nanhai 918391635 :250:100:175
老男孩员工捐款记录表
2)统计分析日志公式信息
累加公式:i=i+1 --> i++
cat test13.txt
oldboy i=i+1 i=0 i=0+1=1 print i --> 1
oldgirl
oldboy i=i+1 i=1 i=1+1=2 print i --> 2
olddog
oldboy i=i+1 i=2 i=2+1=3 print i ---> 3
oldbaby
i=i+1 i=0
# awk '/oldboy/{i=i+1;print i}' test13.txt
1
2
3
# awk '/oldboy/{i=i+1}END{print i}' test13.txt
3
求和公式:i=i+$n 需要将第几列做求和运算
cat test14.txt
1 i=i+$1 i=0 i=0+1 print i ---> 1
2 i=i+$1 i=1 i=1+2 print i ---> 3
3
4
5
6
7
8
9
10
[root@oldboy69 oldboy 12:54:53]# awk '{i=i+$1;print i}' test14.txt
1
3
6
10
15
21
28
36
45
55
# awk '{i=i+$1}END{print i}' test14.txt
总结:
awk用到的参数: -F 指定列分隔符号
awk用到的动作:print 输出指定的信息
gsub 替换指定的信息
awk内置的变量:NR 表示行号信息
NF 表示列号信息
FS : 表示分隔符字段信息
- awk命令语法格式: awk [参数] ‘模式(2种){动作}’ 文件信息
- awk命令使用方法:
参数信息: -F -v
动作信息: print gsub 运算(求和 累加)
擅长将列信息进行取出 - awk高级部分知识:
模式概念: 特殊模式 普通模式
内置变量: NR NF FS
预习:
1.用户权限知识
2.定时任务知识
3.磁盘管理知识 阵列 分区
休息一天时间
第二天测验
网络基础知识
综合架构部署
终极问题:
1.分析secure日志文件
分析某个IP地址失败连接了多少次
[root@jason oldboy]# awk '$(NF-3)~/59.63.166.84/{i=i+1}END{print i}' secure-20161219
2373
[root@jason oldboy]# awk '$11~/59.63.166.84/{i=i+1}END{print i}' secure-20161219
2373
[root@jason oldboy]# awk '$1~/123.150.183.45/{i=i+1}END{print i}' access.log
105
sed -r "[^Mozilla]" access.log| awk '$1{i=i+1}END{print i}' access.log???
[root@jason data 21:27:43]# awk '$(NF-3)~/112.85.42.103/{i=i+1}END{print i}' secure-20161219
18078
[root@jason data 21:27:56]# awk '$11~/112.85.42.103/{i=i+1}END{print i}' secure-20161219
18065
2.分析access日志文件
分析日志文件中流量信息进行统计
[root@jason oldboy]# awk '{sum=sum+$10}END{print sum/1024^3}' access.log
2.30828
[root@jason oldboy]# awk '{i=i+$10}END{print i/1024^3}' access.log
2.30828
03.统计access网站服务日志文件网站流量信息 预存了话费信息 60G 剩余多少流量 求差运算
awk '{sum=sum+$10}END{print 60*1024^3-sum}' access.log
[root@jason oldboy]# awk 'BEGIN{print 61946012777/1024^3}'
57.6917
[root@jason oldboy]# awk 'BEGIN{i=60*1024^3}{i=i-$10}END{print i}' access.log
61946012777
[root@jason oldboy]# awk 'BEGIN{print 61946012777/1024^3}'
57.6917
[root@jason oldboy]# awk '{i=i+$10}END{print 60-i/1024^3}' access.log
57.6917