• 关于awk中NR、FNR、NF、$NF、FS、OFS的说明


    一、NR和FNR
    1.释义
    NR: 表示当前读取的行数
    FNR:当前修改了多少行


    2.举例
    比如现在AWK处理到第五行。第一行没有进行操作,2,3,4,5行进行了操作,那么NR=5,FNR=4
    NR==FNR 表示从起始行到当前行,awk都进行了操作,比如修改,添加等等 ;

    二、NF和$NF
    1.释义
    NF:浏览记录的域的个数
    $NF: 最后一个列,输出最后一个列的内容

    2.举例
    [root@vshi-template shell]# pwd
    /root/guanyy/scripts/shell
    [root@vshi-template shell]# echo $PWD|awk -F/ '{print $NF}'
    shell
    [root@vshi-template shell]# echo $PWD|awk -F/ '{print NF}'
    5

    三、FS和OFS

    1.释义
    FS:指定列分隔符, 当FS为空的时候,awk会把一行中的每个字符,当成一列来处理。
    OFS:列输出分隔符

    2.举例
    (1)FS指定列分隔符

    1. [zhangy@localhost test]$ echo "111|222|333"|awk '{print $1}'  
    2.  111|222|333  
    3. [zhangy@localhost test]$ echo "111|222|333"|awk 'BEGIN{FS="|"}{print $1}'  
    4.  111  
     

    (2)FS也可以使用正则

    1. [zhangy@localhost test]$ echo "111||222|333"|awk 'BEGIN{FS="[|]+"}{print $1}'  
    2. 111  


    (3)FS为空时

    1. [zhangy@localhost test]$ echo "111|222|333"|awk 'BEGIN{FS=""}{NF++;print $0}'  
    2. 1 1 1 | 2 2 2 | 3 3 3  

    (4)RS被设定成非 时, 会成FS分割符中的一个

    1. [zhangy@localhost test]$ cat test1  
    2.  111 222  
    3.  333 444  
    4.  555 666  
    5. [zhangy@localhost test]$ awk 'BEGIN{RS="444";}{print $2,$3}' test1  
    6.  222 333  
    7.  666  

    (5)OFS列输出分隔符

    1. [zhangy@localhost test]$ awk 'BEGIN{OFS="|";}{print $1,$2}' test1  
    2.  111|222  
    3.  333|444  
    4.  555|666  
    5. [zhangy@localhost test]$ awk 'BEGIN{OFS="|";}{print $1 OFS $2}' test1  
    6.  111|222  
    7.  333|444  
    8.  555|666  

    test1只有二列,如果100列,都写出来太麻烦了吧。

    1. [zhangy@localhost test]$ awk 'BEGIN{OFS="|";}{print $0}' test1  
    2.  111 222  
    3.  333 444  
    4.  555 666  
    5. [zhangy@localhost test]$ awk 'BEGIN{OFS="|";}{NF=NF;print $0}' test1  
    6.  111|222  
    7.  333|444  
    8.  555|666  

    为什么第二种方法中的OFS生效呢?个人觉得,awk觉查到列有所变化时,就会让OFS生效,没变化直接输出了。

    NR表示从awk开始执行后,按照记录分隔符读取的数据次数,默认的记录分隔符为换行符,因此默认的就是读取的数据行数,NR可以理解为Number of Record的缩写。

      在awk处理多个输入文件的时候,在处理完第一个文件后,NR并不会从1开始,而是继续累加,因此就出现了FNR,每当处理一个新文件的时候,FNR就从1开始计数,FNR可以理解为File Number of Record。

      NF表示目前的记录被分割的字段的数目,NF可以理解为Number of Field。

    下面以示例程序来进行说明,首先准备两个输入文件class1和class2,记录了两个班级的成绩信息,内容分别如下所示:

    CodingAnts@ubuntu:~/awk$ cat class1
    zhaoyun 85 87
    guanyu 87 88
    liubei 90 86
    CodingAnts@ubuntu:~/awk$ cat class2
    caocao 92 87 90
    guojia 99 96 92

      现在要查看两个班级的所有成绩信息,并在每条信息前加上行号,则可以使用下面的awk指令;

    CodingAnts@ubuntu:~/awk$ awk '{print NR,$0}' class1 class2
    1 zhaoyun 85 87
    2 guanyu 87 88
    3 liubei 90 86
    4 caocao 92 87 90
    5 guojia 99 96 92

      这里的行号就是通过NR来实现的,awk每读取一条记录,NR的值便加一。如果要求每个班级的行号从头开始变化,则需要使用FNR来实现,如下:

    CodingAnts@ubuntu:~/awk$ awk '{print FNR,$0}' class1 class2
    1 zhaoyun 85 87
    2 guanyu 87 88
    3 liubei 90 86
    1 caocao 92 87 90
    2 guojia 99 96 92

      下面的示例结合awk内建变量FILENAME,显示出来的两个班级的成绩信息可以进行更好的区分;

    CodingAnts@ubuntu:~/awk$ awk '{print FILENAME,"NR="NR,"FNR="FNR,"$"NF"="$NF}' class1 class2
    class1 NR=1 FNR=1 $3=87
    class1 NR=2 FNR=2 $3=88
    class1 NR=3 FNR=3 $3=86
    class2 NR=4 FNR=1 $4=90
    class2 NR=5 FNR=2 $4=92

      除了NR和FNR外,上面的示例中还演示了NF的使用,class1中每行有3个字段,而class2中有4个字段,通过$NF就可以很方便的获取最后一个字段了。

  • 相关阅读:
    python 全栈开发,Day67(Django简介)
    python 全栈开发,Day66(web应用,http协议简介,web框架)
    python 全栈开发,Day65(MySQL练习题,参考答案)
    python 全栈开发,Day65(索引)
    python 全栈开发,Day64(视图,触发器,函数,存储过程,事务)
    python 全栈开发,Day63(子查询,MySQl创建用户和授权,可视化工具Navicat的使用,pymysql模块的使用)
    *** 安全沙箱冲突 *** 到 127.0.0.1:9999 的连接已停止
    PosPal银豹收银系统
    m3u8文件简介
    flashbuilder发布release版本
  • 原文地址:https://www.cnblogs.com/klausage/p/14828244.html
Copyright © 2020-2023  润新知