awk命令之NR和FNR变量用法详解

2018年07月18日 42959点热度 11人点赞

0、说明

  刚好用到awk的NR和FNR这两个内建变量。经过一些测试大概熟悉其用法,这里记录下(本文只是用NR和FNR变量来判断当前读入的是第一个还是第二个文件,好对每个文件分别运行指定的脚本。需要注意的是只有读入的文件数小于或等于2个的时候才能使用NR和FNR来判断当前读入的是第几个文件,超过2个文件将无法判断)



1、NR和FNR的作用演示

  NR和FNR都可以为awk读入的文件每行数据增加显示行号。不同之处在于当AWK读入多个文件的时候:NR的行号会一直增加下去,而FNR会在每读入一个新文件时将行号重新由1开始计算



2、接下来拿一个工作中用到的一段命令做示例讲解下(做了修改)

  比如根据上面user.txt和group.txt两个文件,我现在要直接显示出来user.txt文件里那几个员工的:姓名、员工编号、部门名称。则可以用下面命令



3、语句运行过程详细说明

就拿下面这个awk脚本做说明

3.1、总体运行过程如下:

1、首先根据你给定顺序读入第一个文件user.txt,然后将使用'NR==FNR{Z[$3]=$2","$1}NR>FNR{print Z[$1]","$2}' 对user.txt及后面其他文件每行内容做处理。

2、例如当读入第一行数据A0024,张三,10后,首先判断NR==FNR是否为真(因为现在读入的是第一个文件,此时NR和FNR的行号是相等的,所以为真),为真则运行其后面的那段脚本{Z[$3]=$2","$1} ;上面那段脚本运行完后,因为后面还有脚本所以会继续向后运行,此时判断NR>FNR是否为真(因为现在读入的是第一个文件,此时NR和FNR的行号是相等的,所以并不会大于,此处为假),为假时跳过执行其后面的脚本{print Z[$1]","$2}开始处理下一行数据。

3、当第一个文件的所有条目都处理完毕之后,开始读入第二个文件数据。

4、例如当前读入第一行数据10,IT部,六层B区 ,首先判断NR==FNR是否为真(因为现在读入的是第二个文件了,此时NR值增加,FNR则从1开始,所以并不相等,此时为假),为假时跳过执行其后面脚本{Z[$3]=$2","$1} ; 继续向下运行,开始判断NR>FNR是否为真(因为读入的第二个文件,NR值增加,FNR值从1开始重新计算,所以NR大于FNR,此时为真),为真则执行后面脚本{print Z[$1]","$2} 然后开始处理下一行数据

5、当每个文件都处理完则结束。



3.2、user.txt文件每行数据执行{Z[$3]=$2","$1} 脚本时过程:

1、执行脚本为Z[$3]=$2","$1 就是定义了一个数组Z,其下标名为$3的值为$2(做变量替换)。
2、例如此时读入第一行数据:A0024,张三,10 相当于定义了数组Z[10]=张三,A0024 (定义数组Z下标为10的值等于字符串张三,A0024)
3、读入user.txt第二行数据A0019,李四,30 相当于定义Z[30]=李四,A0019 (数组Z下标为30的值等于字符串李四,A0019)
4、后面都一样。



3.3、group.txt文件每行数据执行{print Z[$1]","$2}' 脚本时过程:

1、执行脚本print Z[$1]","$2 就是直接输出数组指定下标及变量对应的值。

2、例如此时读入第一行数据:10,IT部,六层B区 ,相当于print打印 Z[10]","IT部 ,也就是张三,A0024,IT部 (因为前面处理第一个文件数据时已经定好了数组Z,下标为10的值是张三,A0024,然后此处读入的group.txt文件的第一行数据$1的值是10,直接替换引用了),然后继续向下处理下一行数据。

3、读入group.txt第二行数据20,财务部,七层C区 ,相当于打印Z[20]","财务部 ,但是因为前面处理第一个文件user.txt时,其中并没有属于财务部的员工,所以部门编号为20的对应数组下标并没有被定义值,所以这里Z[20]的值就为空,所以最终会打印机出来,财务部

4、后面就都一样了



Chen

健康 · 开心 · 做自己