老男孩教育每日一题-2017年3月28日-awk累计相加

假如现在有个文本,格式如下:

a  1
b  3
c  2
d  7
b  5
a  3 
g  2
f  6
d  9

即左边是随机字母,右边是随机数字,要求写个脚本使其输出格式为:

a  4
b  8
c  2
d  16
f  6
g  2

即将相同的字母后面的数字加在一起,按字母的顺序输出。

答案:

awk ‘{h[$1]=h[$1]+$2}END{for(pol in h)printpol,h[pol]}‘ array_add.txt

演示:

[[email protected] awkfile]# awk‘{h[$1]=h[$1]+$2}END{for(pol in h)print pol,h[pol]}‘ array_add.txt
a 4
b 8
c 2
d 16
f 6
g 2

过程详解:

  • 第一个里程碑-把第二列的数字的总和
[[email protected] awkfile]# cat array_add.txt
a  1
b  3
c  2
d  7
b  5
a  3
g  2
f  6
d  9
[[email protected] awkfile]# awk ‘{sum=sum+$2}END{printsum}‘ array_add.txt
38
  • 第二个里程碑-选择什么作为房间号码

这里只有两列,第一列是字母,第二列是数字是我们要相加的东西。这里我们选择第一列作为房间号码即元素名称。

  • 第三个里程碑-遇到相同的字母再相加

这里就需要用到了awk数组的内容。

sum=sum+$2 这里把sum换成awk数组即可。

[[email protected] awkfile]# awk ‘{h[$1]=h[$1]+$2}‘array_add.txt

没有显示任何过程,不是很好。我们看看他到底如何处理的。一步一步来分析。注意这里我们只关注一个房间a,大家熟练后再同时看多个房间的内容。

[[email protected] awkfile]# awk ‘{h[$1]=h[$1]+$2;print"当前行内容:"$0,"a房间内容:"h["a"]}‘ array_add.txt
当前行内容:a  1 a房间内容:1
当前行内容:b  3 a房间内容:1
当前行内容:c  2 a房间内容:1
当前行内容:d  7 a房间内容:1
当前行内容:b  5 a房间内容:1
当前行内容:a  3 a房间内容:4
当前行内容:g  2 a房间内容:4
当前行内容:f  6 a房间内容:4
当前行内容:d  9 a房间内容:4

我们只关注a房间的内容及h["a"]的内容


行号


当前行的内容


$1的内容


$2的内容


h["a"]之前的内容


h["a"]=h["a"]+$2


h["a"]之后的内容


1


a  1


a


1



h["a"]=空+1


1


2


b  3


b


3


1


不是a房间,不进行计算,h["a"]内容还是1


1


3


c  2


c


2


1


不是a房间,不进行计算,h["a"]内容还是1


1


4


d  7


d


7


1


不是a房间,不进行计算,h["a"]内容还是1


1


5


b  5


b


5


1


不是a房间,不进行计算,h["a"]内容还是1


1


6


a  3


a


3


1


h["a"]=1+3


4


7


g  2


g


2


4


不是a房间,不进行计算,h["a"]内容还是1


4


8


f  6


f


6


4


不是a房间,不进行计算,h["a"]内容还是1


4


9


d  9


d


9


4


不是a房间,不进行计算,h["a"]内容还是1


4

似曾相识的表格呀,我看结合这个表格看看执行过程。

首先读取第一行:

$1内容是a,$2内容是1,这里我们也创建了数组h[$1],我们要计算h[$1]=h[$1]+$2,即h["a"]=空+1.此时h["a"]的内容是1.

然后读取第二行:

$1内容是b,不是我们要的a房间我们跳过,此时h["a"]的内容依然是1

继续往下读情况都是一样的直到读取到第六行

$1内容是a,$2内容是3,这里我们也创建了数组h[$1],我们要计算h[$1]=h[$1]+$2,即h["a"]=1+4.此时h["a"]的内容是4.

awk继续往下读取直到读取到最后一行$1都不是a,所以h["a"]房间的内容不会发生变化。

现在大家再看一下执行过程,注意我们只关注h["a"]房间的内容。

[[email protected] awkfile]# awk ‘{h[$1]=h[$1]+$2;print"当前行内容:"$0,"a房间内容:"h["a"]}‘ array_add.txt
当前行内容:a  1 a房间内容:1
当前行内容:b  3 a房间内容:1
当前行内容:c  2 a房间内容:1
当前行内容:d  7 a房间内容:1
当前行内容:b  5 a房间内容:1
当前行内容:a  3 a房间内容:4
当前行内容:g  2 a房间内容:4
当前行内容:f  6 a房间内容:4
当前行内容:d  9 a房间内容:4

这时候你应该理解他到底如何执行的了。

下面我们看看他完整的执行过程。


行号


当前行的内容


$1的内容


$2的内容


h[$1]之前的内容


h[$1]=h[$1]+$2


h[$1]之后的内容


1


a  1


a


1



h["a"]=空+1


1


2


b  3


b


3



h["b"]=空+3


3


3


c  2


c


2



h["c"]=空+2


2


4


d  7


d


7



h["d"]=空+7


7


5


b  5


b


5


3


h["b"]=3+5


8


6


a  3


a


3


1


h["a"]=1+3


4


7


g  2


g


2



h["g"]=空+2


2


8


f  6


f


6



h["f"]=空+6


6


9


d  9


d


9


7


h["d"]=7+9


16

执行过程如下:

[[email protected] awkfile]# awk ‘{h[$1]=h[$1]+$2;print$1"房间内容:"h
a房间内容:1
b房间内容:3
c房间内容:2
d房间内容:7
b房间内容:8
a房间内容:4
g房间内容:2
f房间内容:6
d房间内容:16
  • 第四个里程碑-只显示最终结果

刚开始我们看着执行过程,可以帮助我们理解awk数组。但是我们的目标是获得每个房间的最后的结果。所以还要用END模式对awk数组进行处理。

[[email protected] awkfile]# awk‘{h[$1]=h[$1]+$2}END{for(pol in h)print pol,h[pol]}‘ array_add.txt
a 4
b 8
c 2
d 16
f 6
g 2

这就是我们要的最终结果。

时间: 2024-12-28 18:46:03

老男孩教育每日一题-2017年3月28日-awk累计相加的相关文章

老男孩教育每日一题-2017年4月28日- MySQL主从复制常见故障及解决方法?

MySQL主从复制常见故障及解决方法? 1.1.1故障1:从库数据与主库冲突 show slave status; 报错:且show slave status\G Slave_I/O_Running:Yes Slave_SQL_Running:No Seconds_Behind_Master:NULL Last_error:Error 'Can't create database 'xiaoliu'; database exists' on query. Default   database:'

老男孩教育每日一题-2017年3月31日-awk数组统计

处理以下文件内容,将域名取出并根据域名进行计数排序处理:(百度和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 要求结

老男孩教育每日一题-2017年5月9日-vim命令粘贴带#号或注释信息格式会出现混乱情况怎么办

1.题目 老男孩教育每日一题-2017年5月9日-vim编辑器使用知识点:vim命令粘贴带#号或注释信息格式会出现混乱情况,有什么方法进行解决?问题说明:每次复制代码时,如果代码里有 //或# 这样的注释就容易让格式乱掉,显示的内容不整齐,并不是所期望的显示格式. 2.参考答案 原因分析: 是由于vim编辑命令的自动缩进功能所影响,因此粘贴带注释的代码时可以取消自动缩进 问题解决: vim在粘贴代码时会自动缩进,把代码搞得一团糟糕,甚至可能因为某行的一个注释造成后面的代码全部被注释掉:最初的解决

老男孩教育每日一题-2017年5月4日-有一个oldboy.txt文件,把里面所有字母都转换成大写

老男孩教育每日一题-2017年5月4日-有一个oldboy.txt文件,把里面所有字母都转换成大写 文件内容如下: [[email protected] oldboy]# cat oldboy.txt  oldboy.blog.51cto.com www.oldboyedu.com 方法一:sed [[email protected] oldboy]# sed 's#[a-z]#\u&#g' oldboy.txt OLDBOY.BLOG.51CTO.COM WWW.OLDBOYEDU.COM 方

老男孩教育每日一题-2017年5月2日-Linux系统中,不小心把chmod命令的权限弄没了,怎么解决?

老男孩教育每日一题-2017年5月2日-Linux系统中,chmod命令没有执行权限(x权限)或者chmod命令文件的权限为000,怎么解决? 解决方法有两种: 方法一: [[email protected] bin]# cp cp /oldboy/chmod.new (此时复制cp命令文件命名叫chmod.new,此时chmod.new文件有就x的权限,但chmod.new不具备有chmod命令的共功能) [[email protected] bin]# cd /oldboy/ [[email

老男孩教育每日一题-2017年05月23日-一个100M的分区,写入0.5K的,或写入1M的,可以写多少?

1.题目 老男孩教育每日一题-2017年05月23日-一个100M的磁盘分区,写入0.5K的文件,或写入1M的文件,分别可以写多少个?为什么? 2.参考答案 一个100M的磁盘分区,写入0.5K的文件,或写入1M的文件,分别可以写多少个?为什么?错误解答:很容易计算1K的个数:100*1000=100000个,1M文件的个数:100/1=100个 解答思想:先答几点知识 a.上面的考试题考察的是文件系统inode和block知识.b.inode是存放文件属性信息的(也包含指向文件实体的指针),默

老男孩教育每日一题-2017年5月8日-请根据以下数字信息,确认相应的端口号,端口号对应的服务名称

1.题目 老男孩教育每日一题-2017年5月8日-网络服务知识点:请根据以下数字信息,确认相应的端口号,端口号对应的服务名称,以及服务主要的作用(简要说明即可) 202122232567686980110111161 2.参考答案 端口号 端口号对应服务名称 服务作用说明 20/21(TCP) FTP服务端口 20端口为FTP传输数据用 21端口为FTP传输控制信息 文件传输协议(File Transfer Protocol) 由于FTP传输效率非常高,在网络上传输大的文件时,一般也采用该协议

老男孩教育每日一题-2017年4月27日-如何正确清理MySQL binlog?

老男孩教育每日一题-2017年4月27日-如何正确清理MySQL binlog? 今天是每日一题陪伴大家的第37天,期待你的进步. 对于题目和答案的任何疑问,请在博客评论区留言. 往期题目索引 http://lidao.blog.51cto.com/3388056/1914205

老男孩教育每日一题-2017年5月7日-加餐-linux下面如何实现,执行rm命令,就显示do not use rm command

1.题目-老男孩教育每日一题-2017年5月7日-加餐-linux下面如何实现,执行rm命令,就显示do not use rm command 2.要求结果 [[email protected] ~]# rm do not use rm command 3.答案 这需要使用linux里面的别名 alias rm='echo do not use rm command' 注意: 上面命令还要放入到/etc/profile里面永久生效 4.详细过程 第一个里程碑-如何显示这行文字 [[email p