zoukankan      html  css  js  c++  java
  • awk之getline()函数运用

    awk之getline()函数运用

    zoer@ubuntu:~$ cat data
    1000
    naughty 500
    cc 400
    zoer 100
    zoer@ubuntu:~$ awk '{if(NR==1){next} print $1,$2}' data
    naughty 500
    cc 400
    zoer 100

    awk可使用shell的重定向符进行重定向输出,如:
    $ awk '$1=100{print $1 > "output_file"}' file
    上式表示如果第一个域的值等于100,则把它输出到output_file中。也可以用>>来重定向输出,但不清空文件,只做追加操作。
    输入重定向需用到getline函数。getline从标准输入、管道或者当前正在处理的文件之外的其他输入文件获得输入。它负责从输入获得下一行的内容,并给NF,NR和FNR等内建变量赋值。如果得到一条记录,getline函数返回1,如果到达文件的末尾就返回0,如果出现错误,例如打开文件失败,就返回-1。如:
    $ awk 'BEGIN{"date"|getline d;split(d,a);print a[2]}'
    执行linux的date命令,并通过管道输出给getline,然后再把输出赋值给自定义变量d,并以默认空格为分割符把它拆分开以数字1开始递增方式为下标存入数组a中,并打印数组a下标为2的值。下面我们再看看一些复杂的运用。

    1)
    文件a
    220 34 50 70
    553 556 32 21
    1 1 14 98 33
    文件b
    10
    8
    2
    要求文件a的每行数据与文件b的相对应的行的值相减,得到其绝对值。
    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

  • 相关阅读:
    HTTP状态码汇总
    树遍历以及图遍历的方法
    HashMap之扩容机制
    MySQL常见的七种锁
    双亲委派机制及作用
    Java进程故障排查思路及步骤
    八大数据结构
    常见的十种排序算法
    使用TortoiseGit操作分支的创建与合并
    Storage Port Drivers
  • 原文地址:https://www.cnblogs.com/gaoyuechen/p/12107651.html
Copyright © 2011-2022 走看看