操作系统三剑客命令-awk

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 : 表示分隔符字段信息

  1. awk命令语法格式: awk [参数] ‘模式(2种){动作}’ 文件信息
  2. awk命令使用方法:
    参数信息: -F -v
    动作信息: print gsub 运算(求和 累加)
    擅长将列信息进行取出
  3. 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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值