awk详解 数组

第1章 awk命令基础

1.1 awk命令执行过程

1、如果BEGIN 区块存在,awk执行它指定的动作。

2、awk从输入文件中读取一行,称为一条输入记录。如果输入文件省略,将从标准输入读取

3、awk将读入的记录分割成字段,将第1个字段放入变量$1中,第2个字段放入$2,以此类推。$0表示整条记录。字段分隔符使用shell环境变量FS或由参数指定。

4、把当前输入记录(数据行)依次与每一个awk命令中awk条件比较,看是否匹配,如果相匹配,就执行对应的动作。如果不匹配,就跳过对应的动作,直到比较完所有的awk命令。

5、当一条输入记录比较了所有的awk命令后,awk读取输入的下一行,继续重复步骤3和4,这个过程一直持续,直到awk读取到文件尾。

6、当awk读完所有的输入行后,如果存在END,就执行相应的动作。

1.2 awk中模式与动作

'pattern{action}'

1.2.1 在awk眼中的行与列

field     字段,列

record    记录,行

 

1.3 awk默认有一把“菜刀”

空格系列 (单独的空格,连续的空格,tab键)

 -F        指定分隔符 

 -vFS

 FS  == field sep       每一列的分隔符

 OFS ==output field sep  输出每一列的时候使用的分隔符

1.4 awk的内置变量


变量


含义


英文全写


FS  


 每一列的分隔符


field sep      


NF  


 每一行有多少列


number  of field


OFS 


 输出每一列的时候使用的分隔符


output field sep


NR  


 记录号 行号


number of record


RS  


 每一行的分隔符(每一行的结束标记)


 


$数字


 取某一列


 


$0  


 取出这一行


 

1.4.1 $NF的使用

$NF 表示最后一列,(NF-1)表示倒数第二列,以此类推。

[root@znix ~]# awk -F: '{print NF}' passwd.txt

7

7

……

[root@znix ~]# awk -F: '{print $NF}' passwd.txt

/bin/bash

/sbin/nologin

/sbin/nologin

[root@znix ~]# awk -F: '{print $(NF-1)}' passwd.txt

/root

/bin

/sbin

1.5 【练习题】awk如何使用正则?

1)      显示Xiaoyu的姓氏和ID号码

2)      显示所有ID号码最后一位数字是1或5的人的全名

3)      姓氏是Zhang的人,显示他的第二次捐款金额及她的名字

4)      显示Xiaoyu的捐款.每个值时都有以$开头.如$520$200$135

1.5.1 环境准备

mkdir -p /server/files/

cat >>/server/files/reg.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

1.5.1.1 内容释义:

第一列是姓氏

第二列是名字

第一第二列合起来就是姓名

第三列是对应的ID号码

最后三列是三次捐款数量

1.5.2 显示出第二列中包含X 的。

$2~表示第二列所有的内容。 ~表示所有

              在这里X比较特殊,是大写的,awk中区分大小写。

[root@znix files]# awk '$2~/X/' reg.txt

Zhang Xiaoyu    390320151  :155:90:201

Wang  Xiaoai    3515064655 :50:95:135

1.5.3 显示Xiaoyu的姓氏和ID号码

[root@znix files]# awk '$2~/Xiaoyu/{print $1,$3}' reg.txt

Zhang 390320151

1.5.4 显示所有ID号码最后一位数字是1或5的人的全名

[root@znix files]# awk '$3~/(1|5)$/{print $1,$2}' reg.txt

[root@znix files]# awk '$3~/[15]$/{print $1,$2}' reg.txt

Zhang Xiaoyu

Wu Waiwai

Wang Xiaoai

Li Youjiu

Lao Nanhai

1.5.5 姓氏是Zhang的人,显示他的第二次捐款金额及她的名字

先找到,再进行输出。(NF-1) 表示倒数第二列。

[root@znix files]# awk -F "[ :]+" '$1~/Zhang/{print $2,$(NF-1)}' reg.txt

Dandan 100

Xiaoyu 90

1.5.6 显示Xiaoyu的捐款.每个值时都有以$开头.如$520$200$135

tr 命令进行替换,格式比较简单tr  "要替换什么" "替换成什么"

[root@znix files]# awk '$2~/Xiaoyu/{print $4}' reg.txt |tr ":" "$"

$155$90$201

[root@znix files]# awk '$2~/Xiaoyu/{gsub(/:/,"$",$NF);print $NF}' reg.txt

$155$90$201

1.6 awk中的$0是什么鬼?

$0表示文件中整条记录(行)的内容,在这里加$0 与不加$0 相同。

[root@znix files]# awk '/Zhang/' reg.txt

Zhang Dandan    41117397   :250:100:175

Zhang Xiaoyu    390320151  :155:90:201

[root@znix files]# awk '$0~/Zhang/' reg.txt

Zhang Dandan    41117397   :250:100:175

Zhang Xiaoyu    390320151  :155:90:201

1.7 awk中的替换

在awk中,可以用来替换的有三个函数:sub gsub gensub

1.7.1 使用gusb 函数进行替换

       gsub(r, s [, t]) 

               r  /找谁/

               s  "替换成什么"

               [] 替换那个部分的

       表示为: gsub(/找谁/,"替换成什么",替换那个部分的)

1.7.2 替换文本中的内容

题目:显示Xiaoyu的捐款.每个值时都有以$开头.如$520$200$135

       中间使用分号分割 ;

[root@znix files]# awk '{gsub(/:/,"$",$NF);print $0}' reg.txt

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

       添加上限定条件后,取到的结果会更加的精确。

[root@znix files]# awk '$2~/Xiaoyu/{gsub(/:/,"$",$NF);print $NF}' reg.txt

$155$90$201

1.8 【练习题】判断当前系统上所有用户的shell是否为可登录shell(即用户的shell不是/sbin/nologin),如果是显示用户名字

不包含:,在awk中不包含可以使用表示。

$NF        表示这个文件的最后一列

-F             将分隔符指定为:

[root@znix ~]# awk -F: '$NF!~/nologin$/{print $1}' /etc/passwd

root

sync

shutdown

halt

oldboy

oldgirl

test

stu01

stu02

stu03

znix

1.8.1 【对齐】输出的结果更美观整齐--column命令

-t  -t参数让他对齐。

[root@znix files]# awk 'BEGIN{print "姓","名"}{print $1,$2}' reg.txt |column -t

姓     名

Zhang  Dandan

Zhang  Xiaoyu

Meng   Feixue

Wu     Waiwai

Liu    Bingbing

Wang   Xiaoai

Zi     Gege

Li     Youjiu

Lao    Nanhai

 

第2章 awk中BEGIN 和 END

2.1 怎么把正则表达式作为条件

BEGIN:开始

              里面的内容会在awk读取文件之前运行

              在BEGIN里面定义awk的内置变量

      

END

END{} 里面放入内容,在读取完文件内容后执行

              先计算,在END里面输出结果 

              先计算再输出

2.1.1 【一个栗子】执行完输出后,再输出一个“结束”

[root@znix files]# awk '{print $0}END{print "结束"}' reg.txt

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

结束

2.2 【企业案例】统计/etc/services文件里面的空行数量

2.2.1 使用awk的END模式

前面的i++先进行计算,再输出结果。

i=i+1 与i++ 相同。

[root@znix ~]# awk '/^$/{i=i+1}END{print i}' /etc/services

16

[root@znix ~]# awk '/^$/{i++}END{print i}' /etc/services

16

2.2.2 查看i++的执行过程

i++与i=i+1相同。

i=i+$0  累计相加 计算总和

i=i+1  i++   计数

[root@znix ~]# awk '/^$/{i++;print i}' /etc/services

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

2.2.3 其他方法:

uniq -c  uniq 命令把相邻两行一样的合并,-c为统计出现的次数

[root@znix ~]# awk '/^$/' /etc/services|uniq -c

    16

[root@znix ~]# awk '/^$/' /etc/services|wc -l

16

2.3 【案例】seq 100 >num.txt ,计算这个文件每一行相加的结果

i=i+$0  累计相加 计算总和

i=i+1  i++   计数

没有赋初始值的时候
i++ 先返回0,再加1,第二次调用的时候先返回1,再加1,以此类推

[root@znix ~]# awk '{i=i+$0}END{print i}' num.txt

5050

第3章 awk数组

3.1 数组是用来做什么的?

分类计算,用于统计。

3.1.1 他能够干些什么?

统计日志文件中 图片.jpg 出现了多少次

统计日志文件中 图片.png 出现了多少次

统计更累的信息

3.2 数组详解---"老男孩酒店"

假设我们的酒店叫老男孩教育酒店

老男孩教育酒店<===>hotel

酒店里面有几个房间110,119,120,114,401这几个房间。

老男孩教育酒店的110房间<===> hotel[110]

老男孩教育酒店的119房间<===> hotel[119]

老男孩教育酒店的120房间<===> hotel[121]

酒店房间里面入住客人

3.2.1 如何查看房间里住的是哪位客人?

[root@znix files]# awk 'BEGIN{hotel[110]="lidao" ;hotel[119]="tanjiaoshou";hotel[121]="taojin";print hotel[110],hotel[121],hotel[119]}'

lidao taojin tanjiaoshou

3.2.2 使用for语句,对酒店进行循环/查房

awk 'BEGIN{hotel[110]="lidao" ;hotel[119]="tanjiaoshou";hotel[121]="taojin";

for(pol in hotel) 

print pol,hotel[pol]

}'

格式:

for(变量 in 数组)  使用变量对酒店进行循环/查房

print pol,hotel[pol] :

pol       得到-房间的号码

hotel[pol] 哪个酒店的哪个房间

[root@znix files]# awk 'BEGIN{hotel[110]="lidao" ;hotel[119]="tanjiaoshou";hotel[121]="taojin"

> for(pol in hotel)

> print pol,hotel[pol]

> }'

110 lidao

121 taojin

119 tanjiaoshou

3.3 【企业面试题】统计域名访问次数(去重统计)。处理以下文件内容,将域名取出并根据域名进行计数排序处理:(百度和sohu面试题)

http://www.etiantian.org/index.html

http://www.etiantian.org/1.html

http://post.etiantian.org/index.html

http://mp3.etiantian.org/index.html

http://www.etiantian.org/3.html

http://post.etiantian.org/2.html

3.3.1 方法一:sort uniq

uniq 命令 把相邻两行一样的合并

[root@znix ~]# awk -F '[/]+' '{print $2}' www.txt |uniq -c

      2 www.etiantian.org

      1 post.etiantian.org

      1 mp3.etiantian.org

      1 www.etiantian.org

sort 排序,默认是按照字母的顺序

[root@znix ~]# awk -F '[/]+' '{print $2}' www.txt |sort

mp3.etiantian.org

post.etiantian.org

www.etiantian.org

www.etiantian.org

www.etiantian.org

3.3.2 方法2 awk数组

3.3.2.1 第一步 取出域名

[root@znix ~]# awk -F '[/]+' '{print $2}' www.txt

www.etiantian.org

www.etiantian.org

post.etiantian.org

mp3.etiantian.org

www.etiantian.org

3.3.2.2 第二步 显示

; 两条命令之间用分号分割。

[root@znix ~]# awk -F '/+' '{hotel[$2]++;print hotel["www.etiantian.org"]}' www.txt

1

2

2

2

3

3.3.2.3 第三步 显示结果

[root@znix ~]# awk -F '/+' '{hotel[$2]++}END{for(pol in hotel)print pol,hotel[pol]}' www.txt

mp3.etiantian.org 1

post.etiantian.org 1

www.etiantian.org 3

第4章 课后题目:

两个文件  secure.zip  access.zip

4.1 统计secure文件中谁在破解你的密码(统计出破解你密码的ip地址出现的次数)

4.1.1 方法一

[root@znix test]# awk '/Failed/{fa[$(NF-3)]++}END{for(pol in fa)print pol,fa[pol]}' secure-20161219|column -t

218.65.30.126    17163

218.65.30.61     17163

125.16.71.175    4

169.46.38.74     9

183.136.238.78   30

218.2.0.16       10

122.228.238.66   1

……

4.1.2 方法二

[root@znix test]# awk '/Failed/{print $(NF-3)}' secure-20161219 |sort|uniq -c|sort -n  

4.1.3 结果统计

[root@znix test]# awk '/Failed/{fa[$(NF-3)]++}END{for(pol in fa)print pol,fa[pol]}' secure-20161219|column -t|wc -l

88

4.2 统计access.log文件中对ip地址去重并统计重复数

[root@znix test]# awk '{hotel[$1]++}END{for(pol in hotel)print pol,hotel[pol]}' access.log |head -3

101.226.125.115 284

180.154.137.177 516

101.226.125.116 127

4.3 统计access.log文件中网站一共使用了多少流量

[root@znix test]# awk '{i=i+$10}END{print i}' access.log

2478496663

时间: 2024-10-01 11:04:06

awk详解 数组的相关文章

linux正则表达式awk详解_正则表达式

awk和sed一样是流式编辑器,它也是针对文档中的行来操作的,一行一行的去执行.awk比sed更加强大,它能做到sed能做到的,同样也能做到sed不能做到的.awk常用来分段: awk不用加任何参数就可以实现 + ? * .  | 这些特殊符号: 1.截取文档中的某个段 [root@yonglinux ~]# head -n2 passwd |awk -F: '{print $1}' root bin [root@yonglinux ~]# head -n2 passwd |awk -F: '{

awk详解

awk   工具详解     awk历史   AWK 是一种优良的文本处理 工具,Linux 及Unix 环境中现有的功能最强大的数据处理 引擎之一.这种编程及数据操作语言(其名称得自于它的创始人 Alfred Aho .Peter Weinberger 和 Brian Kernighan 姓氏的首个字母)的最大功能取决于一个人所拥有的知识. AWK 提供了极其强大的功能:可以进行正则表达式的匹配,样式装入.流控制.数学运算符.进程控制语句甚至于内置的变量和函数.它具备了一个完整的语言所应具有的

awk 详解+实例

1. awk简介 awk是一种编程语言,用于在linux/unix下对文本和数据进行处理.数据可以来自标准输入.一个或多个文件,或其它命令的输出.它支持用户自定义函数和动态正则表达式等先进功能,是linux/unix下的一个强大编程工具.它在命令行中使用,但更多是作为脚本来使用.awk的处理文本和数据的方式是这样的,它逐行扫描文件,从第一行到最后一行,寻找匹配的特定模式的行,并在这些行上进行你想要的操作.如果没有指定处理动作,则把匹配的行显示到标准输出(屏幕),如果没有指定模式,则所有被操作所指

PHP二维数组排序问题详解(数组键值排序)

根据某个键值对二维数组进行排序是个常见问题,这里总结一个函数,可同时对两个键值分别排序,当然想要更多的话就自行解决吧. 但是如果需要排序的数组是一个二维数组,需要按照数组的键值排序,如下面这个二维数组,需要按照sort键名来排序,那么array_multisort() 就无法直接实现了: 实例一,  代码如下 复制代码 $arr = array( array( 'sort' => 3, 'a' => 'a', 'b' => 'b' ), array( 'sort' => 5, 'a

linux正则表达式awk详解

awk和sed一样是流式编辑器,它也是针对文档中的行来操作的,一行一行的去执行.awk比sed更加强大,它能做到sed能做到的,同样也能做到sed不能做到的.awk常用来分段: awk不用加任何参数就可以实现 + ? * .  | 这些特殊符号: 1.截取文档中的某个段 [root@yonglinux ~]# head -n2 passwd |awk -F: '{print $1}' root bin [root@yonglinux ~]# head -n2 passwd |awk -F: '{

linux awk时间计算脚本及awk命令详解_linux shell

在linux如果计划时间是个麻烦事, 用awk脚本如下 BEGIN {FS=":";OFS=":"} {total_seconds=total_seconds+$3} total_seconds>=60 {total_seconds=total_sconds-60 $2=$2+1 } {total_minutes=total_minutes+$2 $2=$2+1 } {total_minutes=total_minutes+$2} total_minutes&

awk正则表达式和内置函数的使用方法实例详解_linux shell

awk正则表达式及内置函数实例详解: 1.模糊匹配: 复制代码 代码如下: awk '{if($3~/97/) print $0}' data.f:如果第三项中含有"97"则打印该行 awk '{if($4!~/ufcx/) print $0}' data.f:如果第三项中不含ufcx有则打印 2.精确匹配: 复制代码 代码如下: awk '{if($5==66) print $0}' data.f:如果第五项是66则打印 awk '{if($5!=66)print $0}' data

C++的array数组容器详解

数组容器, 是存储数组的容器, 是C类型数组的扩充, 可以使用迭代器进行操作; 例如"std::array<int, 5>", 需要注意的是, 如果直接进行赋值, "std::array<int, 5> ia = {1, 2, 3, 4, 5}; " 在GCC下会有警告: "missing braces around initializer for 'std::array<int, 5u>::value_type [5]

JavaScript数组和循环详解

          JavaScript数组和循环详解           这篇文章主要介绍了JavaScript数组和循环详解,本文讲解了循环遍历数组.按顺序存储和访问值.以相反的顺序存储和访问值.在数组中搜索等内容,需要的朋友可以参考下               数组是元素的一个有序组合.在JavaScript中,数组可以使用正式的对象表示法来创建,或者可以使用直接量表示法来初始化.   代码如下: var arrObject = new Array("val1", "