try vuuv.github.io or somewhere else.
分类:
2011-10-07 15:00:05
原文地址:awk之getline函数运用 作者:zooyo
[解析]
getline依次按行读取文件b里的值,然后for循环依次和文件a里的每个字段进行比较,如果比它大就j-$i,要是比它小就$i-j,保证文件相减都是整数,当然更法很多,可以判断是否小于0,小于0就负负为正,也可以替换到负号这个符号等等。总结的说getline函数可以实现2个文件的同步读取而实现一系列的操作。下面是数组的解法:
2)
文件a
aaa
bbb
ccc
ddd
文件b
111 xxx
222 xxx
333 xxx
444 xxx
要求文件a里的数据依次替换文件b中的xxx字样。
[解析]
相信大家已经熟悉getline的用法了吧。呵呵,再看看数组的用法,数组是awk的灵魂,但是有点耗费资源,特别是数百兆上G文件的时候,它挺费劲,大家酌情考虑。
在awk运用中,getline可以把当前行的下一行的内容读取给一个变量,也可以在当前行直接把操作转移到下一行操作,有点类似sed里的n功能,下面看看它的这个特性的使用:
3)
要求统计每个小时内的访问总和:
2011-07-20 09:57:01
239
2011-07-20 11:03:01
248
2011-07-20 10:29:01
250
2011-07-20 09:56:01
255
2011-07-20 10:45:01
269
2011-07-20 11:27:01
272
2011-07-20 10:28:01
273
2011-07-20 11:32:01
274
2011-07-20 10:44:01
303
2011-07-20 11:36:01
316
[解析]
因为数据可以看出是很有规律的一行是时间,下一样就是数值,所以把时间赋值给一个变量,然后读取到下一行,把下一行的数值累加给这个时间段为下标的数组a,最后取出结果。
[解析]
这个getline的意义完全不一样了,当匹配到有冒号的行时执行{action},getline是读取下一行的数据给变量x,然后再根据这个时间的下标把x累加给数组a,最后取出结果。执行的结果都是一样的,大家好好揣摩一下getline的用法区别。
4)
[解析]
惯用思路想用awk的asorti()函数来排序,新的问题又来了,那如何让后一行减前面一行呢?看来只有先排序后再利用awk逐行执行的个性来操作了。这里我们先把要排序操作的命令记录到一个变量里,再利用getline函数就可以逐行把排序后的文本一一读取到awk中,然后完成相减后输出。这个思路真的很好,没想到直接类似shell的eval $cmd这样的操作手法。 代码不这么风骚点的话,还是老老实实的按照传统模式来吧:
5)
cat file
4235 3
7 0.051 0.30
0.625 0.675 0.675
8 0.617 0.30
0.419 0.517 0.528
9 0.333 0.30
0.452 0.484 0.493
13 0
14 0
51547 1
2 1.000 0.30
第一行第2个字段为3,表示下面会出现3份这样的数据,为0就没有,为1是会出现一份数据,现在要求把这样的数据复制一份:
4235 3
7 0.051 0.30
0.625 0.675 0.675
8 0.617 0.30
0.419 0.517 0.528
9 0.333 0.30
0.452 0.484 0.493
4235 3
7 0.051 0.30
0.625 0.675 0.675
8 0.617 0.30
0.419 0.517 0.528
9 0.333 0.30
0.452 0.484 0.493
13 0
13 0
14 0
14 0
51547 1
2 1.000 0.30
4.303 4.485 4.614
51547 1
2 1.000 0.30
4.303 4.485 4.614
[解析]
判断$2是0的话就直接打印双份,否则通过计算出的行数用for循环通过getline读取下一行累加起来,再统一打印双份。