0、说明
刚好用到awk的NR和FNR这两个内建变量。经过一些测试大概熟悉其用法,这里记录下(本文只是用NR和FNR变量来判断当前读入的是第一个还是第二个文件,好对每个文件分别运行指定的脚本。需要注意的是只有读入的文件数小于或等于2个的时候才能使用NR和FNR来判断当前读入的是第几个文件,超过2个文件将无法判断)
1、NR和FNR的作用演示
NR和FNR都可以为awk读入的文件每行数据增加显示行号。不同之处在于当AWK读入多个文件的时候:NR的行号会一直增加下去,而FNR会在每读入一个新文件时将行号重新由1开始计算
1.1、首先创建两个示例文件
[root@imzcy ~]# cat user.txt #逗号分隔的三列分别表示:工号、姓名、部门编号
A0024,张三,10
A0019,李四,30
A0015,王五,40
A0021,孙六,80
[root@imzcy ~]#
[root@imzcy ~]# cat group.txt #逗号分隔的三列分别表示:部门编号、部门名称、部门位置
10,IT部,六层B区
20,财务部,七层C区
30,设计部,七层B区
40,人事部,六层C区
50,采购部,七层A区
60,招聘部,六层A区
70,法务部,七层D区
80,发展部,六层D区
90,总经办,六层E区
[root@imzcy ~]#
1.2、在AWK中调用NR变量,查看其作用
1.2.1、可以看到NR可以为读入的文件添加行号(行号从1开始,NR显示行号、$0显示行所有内容)
[root@imzcy ~]# awk '{print NR,$0}' user.txt
1 A0024,张三,10
2 A0019,李四,30
3 A0015,王五,50
4 A0021,孙六,80
[root@imzcy ~]#
1.2.2、根据下面输出可以看到,当NR读入多个文件的时候,行号会从上一个文件结束值增加的
[root@imzcy ~]# awk '{print NR,$0}' user.txt group.txt
1 A0024,张三,10
2 A0019,李四,30
3 A0015,王五,50
4 A0021,孙六,80
5 10,IT部,六层B区
6 20,财务部,七层C区
7 30,设计部,七层B区
8 40,人事部,六层C区
9 50,采购部,七层A区
10 60,招聘部,六层A区
11 70,法务部,七层D区
12 80,发展部,六层D区
13 90,总经办,六层E区
[root@imzcy ~]#
#1.3、在AWK中调用FNR变量,查看其作用
1.3.1、可以看到FNR同样也可以为读入的文件添加行号(行号从1开始,NR显示行号、$0显示行所有内容)
[root@imzcy ~]# awk '{print FNR,$0}' user.txt
1 A0024,张三,10
2 A0019,李四,30
3 A0015,王五,50
4 A0021,孙六,80
[root@imzcy ~]#
1.3.2、根据下面输出可以看到,当NR读入多个文件的时候,行号会从下一个文件开始时从新计算值增加的
[root@imzcy ~]# awk '{print FNR,$0}' user.txt group.txt
1 A0024,张三,10
2 A0019,李四,30
3 A0015,王五,50
4 A0021,孙六,80
1 10,IT部,六层B区
2 20,财务部,七层C区
3 30,设计部,七层B区
4 40,人事部,六层C区
5 50,采购部,七层A区
6 60,招聘部,六层A区
7 70,法务部,七层D区
8 80,发展部,六层D区
9 90,总经办,六层E区
[root@imzcy ~]#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
1.1、首先创建两个示例文件
[root@imzcy~]# cat user.txt #逗号分隔的三列分别表示:工号、姓名、部门编号
A0024,张三,10
A0019,李四,30
A0015,王五,40
A0021,孙六,80
[root@imzcy~]#
[root@imzcy~]# cat group.txt #逗号分隔的三列分别表示:部门编号、部门名称、部门位置
10,IT部,六层B区
20,财务部,七层C区
30,设计部,七层B区
40,人事部,六层C区
50,采购部,七层A区
60,招聘部,六层A区
70,法务部,七层D区
80,发展部,六层D区
90,总经办,六层E区
[root@imzcy~]#
1.2、在AWK中调用NR变量,查看其作用
1.2.1、可以看到NR可以为读入的文件添加行号(行号从1开始,NR显示行号、$0显示行所有内容)
[root@imzcy~]# awk '{print NR,$0}' user.txt
1A0024,张三,10
2A0019,李四,30
3A0015,王五,50
4A0021,孙六,80
[root@imzcy~]#
1.2.2、根据下面输出可以看到,当NR读入多个文件的时候,行号会从上一个文件结束值增加的
[root@imzcy~]# awk '{print NR,$0}' user.txt group.txt
1A0024,张三,10
2A0019,李四,30
3A0015,王五,50
4A0021,孙六,80
510,IT部,六层B区
620,财务部,七层C区
730,设计部,七层B区
840,人事部,六层C区
950,采购部,七层A区
1060,招聘部,六层A区
1170,法务部,七层D区
1280,发展部,六层D区
1390,总经办,六层E区
[root@imzcy~]#
#1.3、在AWK中调用FNR变量,查看其作用
1.3.1、可以看到FNR同样也可以为读入的文件添加行号(行号从1开始,NR显示行号、$0显示行所有内容)
[root@imzcy~]# awk '{print FNR,$0}' user.txt
1A0024,张三,10
2A0019,李四,30
3A0015,王五,50
4A0021,孙六,80
[root@imzcy~]#
1.3.2、根据下面输出可以看到,当NR读入多个文件的时候,行号会从下一个文件开始时从新计算值增加的
[root@imzcy~]# awk '{print FNR,$0}' user.txt group.txt
1A0024,张三,10
2A0019,李四,30
3A0015,王五,50
4A0021,孙六,80
110,IT部,六层B区
220,财务部,七层C区
330,设计部,七层B区
440,人事部,六层C区
550,采购部,七层A区
660,招聘部,六层A区
770,法务部,七层D区
880,发展部,六层D区
990,总经办,六层E区
[root@imzcy~]#
2、接下来拿一个工作中用到的一段命令做示例讲解下(做了修改)
比如根据上面user.txt和group.txt两个文件,我现在要直接显示出来user.txt文件里那几个员工的:姓名、员工编号、部门名称。则可以用下面命令
2.1、根据user.txt和group.txt文件信息,直接输出:员工姓名,员工编号,部门名称
[root@imzcy ~]# awk -F , 'NR==FNR{Z[$3]=$2","$1}NR>FNR{print Z[$1]","$2}' user.txt group.txt
张三,A0024,IT部
,财务部
李四,A0019,设计部
,人事部
王五,A0015,采购部
,招聘部
,法务部
孙六,A0021,发展部
,总经办
[root@imzcy ~]#
因为group.txt里面有的部门在user.txt那个文件中没有,并且我直接打印了$2,所以也都会显示出来
2.2、加if语句做判断,只有当数组Z[$1]对应的值不为空的时候,才会打印出$2的值。
[root@imzcy ~]# awk -F , 'NR==FNR{Z[$3]=$2","$1}NR>FNR{if(Z[$1]!=""){print Z[$1]","$2}}' user.txt group.txt
张三,A0024,IT部
李四,A0019,设计部
王五,A0015,采购部
孙六,A0021,发展部
[root@imzcy ~]#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2.1、根据user.txt和group.txt文件信息,直接输出:员工姓名,员工编号,部门名称
[root@imzcy~]# awk -F , 'NR==FNR{Z[$3]=$2","$1}NR>FNR{print Z[$1]","$2}' user.txt group.txt
张三,A0024,IT部
,财务部
李四,A0019,设计部
,人事部
王五,A0015,采购部
,招聘部
,法务部
孙六,A0021,发展部
,总经办
[root@imzcy~]#
因为group.txt里面有的部门在user.txt那个文件中没有,并且我直接打印了$2,所以也都会显示出来
2.2、加if语句做判断,只有当数组Z[$1]对应的值不为空的时候,才会打印出$2的值。
[root@imzcy~]# awk -F , 'NR==FNR{Z[$3]=$2","$1}NR>FNR{if(Z[$1]!=""){print Z[$1]","$2}}' user.txt group.txt
张三,A0024,IT部
李四,A0019,设计部
王五,A0015,采购部
孙六,A0021,发展部
[root@imzcy~]#
3、语句运行过程详细说明
就拿下面这个awk脚本做说明
[root@imzcy ~]# awk -F , 'NR==FNR{Z[$3]=$2","$1}NR>FNR{print Z[$1]","$2}' user.txt group.txt
1
[root@imzcy~]# awk -F , 'NR==FNR{Z[$3]=$2","$1}NR>FNR{print Z[$1]","$2}' user.txt group.txt
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、后面就都一样了