awk之getline()函数运用
来源:互联网 发布:usb共享网络是什么意思 编辑:程序博客网 时间:2024/06/13 03:23
- $ awk '$1=100{print $1 > "output_file"}' file
输入重定向需用到getline函数。getline从标准输入、管道或者当前正在处理的文件之外的其他输入文件获得输入。它负责从输入获得下一行的内容,并给NF,NR和FNR等内建变量赋值。如果得到一条记录,getline函数返回1,如果到达文件的末尾就返回0,如果出现错误,例如打开文件失败,就返回-1。如:
- $ awk 'BEGIN{"date"|getline d;split(d,a);print a[2]}'
553 556 32 21
1 1 14 98 33
8
2
- awk '{getline j<"b";for(i=1;i<=NF;i++){$i>j?$i=$i-j:$i=j-$i}}1' a|column -t
- 210 24 40 60
- 545 548 24 13
- 1 1 12 96 31
[解析]
getline依次按行读取文件b里的值,然后for循环依次和文件a里的每个字段进行比较,如果比它大就j-$i,要是比它小就$i-j,保证文件相减都是整数,当然更法很多,可以判断是否小于0,小于0就负负为正,也可以替换到负号这个符号等等。总结的说getline函数可以实现2个文件的同步读取而实现一系列的操作。下面是数组的解法:
- awk 'ARGIND==1{a[FNR]=$1;next}{for(i=1;i<=NF;i++)$i=$i-a[FNR];$0=gensub(/-/,"","g")}1' b a
2)
文件a
aaa
bbb
ccc
ddd
文件b
111 xxx
222 xxx
333 xxx
444 xxx
要求文件a里的数据依次替换文件b中的xxx字样。
- awk '{getline i<"a"}/xxx/{sub("xxx",i,$2)}1' b
- 111 aaa
- 222 bbb
- 333 ccc
- 444 ddd
[解析]
相信大家已经熟悉getline的用法了吧。呵呵,再看看数组的用法,数组是awk的灵魂,但是有点耗费资源,特别是数百兆上G文件的时候,它挺费劲,大家酌情考虑。
- awk 'NR==FNR{a[FNR]=$1;next}/xxx/{++i;$2=a[i]}1' a b
在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
- awk -F':' '{i=$1;getline;a[i]+=$1}END{for(j in a)print j,a[j]}' file
[解析]
因为数据可以看出是很有规律的一行是时间,下一样就是数值,所以把时间赋值给一个变量,然后读取到下一行,把下一行的数值累加给这个时间段为下标的数组a,最后取出结果。
- awk -F':' '/:/{getline x;a[$1]+=x}END{for(i in a) print i,a[i]}' file
[解析]
这个getline的意义完全不一样了,当匹配到有冒号的行时执行{action},getline是读取下一行的数据给变量x,然后再根据这个时间的下标把x累加给数组a,最后取出结果。执行的结果都是一样的,大家好好揣摩一下getline的用法区别。
4)
TL_tKUFyGbu642/1 scaffold_2 999991
V4_CUctkGbu642/1 scaffold_30 999990
B6_SIhaqGbu642/1 scaffold_3 9999932
V4_CUctkGbu642/1 scaffold_30 999990
TL_tKUFyGbu642/1 scaffold_2 999991 1
r9_cz3IwGbu642/1 scaffold_3 9999914 8999923
B6_SIhaqGbu642/1 scaffold_3 9999932 18
- awk -vcmd="sort -k3,3n <file" 'BEGIN{while(cmd|getline){print $0 FS (i?$3-i:"");i=$3}}
[解析]
惯用思路想用awk的asorti()函数来排序,新的问题又来了,那如何让后一行减前面一行呢?看来只有先排序后再利用awk逐行执行的个性来操作了。这里我们先把要排序操作的命令记录到一个变量里,再利用getline函数就可以逐行把排序后的文本一一读取到awk中,然后完成相减后输出。这个思路真的很好,没想到直接类似shell的eval $cmd这样的操作手法。 代码不这么风骚点的话,还是老老实实的按照传统模式来吧:
- sort -k3,3n file|awk 'NR>1{$0=$0 FS $3-x}{x=$3}1
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
- awk '{if($2==0){print $0"\n"$0}else{c=$2*2;i=$0;for(n=0;n++<c;){getline;i=i"\n"$0};print i"\n"i}}' file
[解析]
判断$2是0的话就直接打印双份,否则通过计算出的行数用for循环通过getline读取下一行累加起来,再统一打印双份。
- awk之getline()函数运用
- awk--getline函数
- awk 笔记之四 getline
- Linux中awk之getline命令
- C++之getline()函数
- awk(3)-awk getline
- awk调用shell命令与getline和system函数
- awk调用shell命令与getline和system函数
- awk调用shell命令与getline和system函数
- 文件读取之getline函数
- awk与getline
- awk读输入(getline)
- awk getline命令解析
- awk+system+getline
- [转]Awk基础入门之二:读书笔记-awk运用
- awk运用
- awk运用
- c++中cin、cin.get()、cin.getline()、getline()、gets()等函数的运用
- java泛型
- 电子标签的芯片组成及其功能
- py2exe打包pyqt程序
- 黑马程序员——Java练习笔记——IO流
- 二级指针的三种内存模型
- awk之getline()函数运用
- 学习笔记(3): QtConcurrent::run()的使用
- 堆排序
- HDU 1286 找新朋友【欧拉函数】
- c++ 利用 chilkat 库发送 html邮件
- 操作系统概论之处理器管理
- Java实现简单的图书管理系统
- 再次理解泛型
- 阿里巴巴2014笔试题详解(9月22北京)