转载:https://www.cnblogs.com/irockcode/p/7044722.html

nr,表示awk开始执行程序后所读取的数据行数.

fnr,与nr功用类似,不同的是awk每打开一个新文件,fnr便从0重新累计.

下面看两个例子:

1,对于单个文件nr 和fnr 的 输出结果一样的 :

2,但是对于多个文件 :

在看一个例子关于nr和fnr的典型应用:

现在有两个文件格式如下:

想要得到的结果是将用户名,帐号和金额在同一行打印出来,如下:

张三|000001|10

张三|000001|20

李四|000002|30

李四|000002|15

执行如下代码

注释:

由nr=fnr为真时,判断当前读入的是第一个文件a,然后使用{a[$2]=$0;next}

循环将a文件的每行记录都存入数组a,并使用$2第2个字段作为下标引用.

由nr=fnr为假时,判断当前读入了第二个文件b,然后跳过{a[$2]=$0;next},

对第二个文件cdr的每一行都无条件执行{print a[$1]"|"$2},

此时变量$1为第二个文件的第一个字段,与读入第一个文件时,采用第一个文件第二个字段$2为数组下标相同.

因此可以在此使用a[$1]引用数组。

=========================================================================

下面是cu大神jason680的详细过程分析

awk -f'|' 'nr==fnr{a[$2]=$0;next}{print a[$1] fs $2}' a b

there is no begin block, and fs="|" by -f'|' argument

没有开始模块,直接识别-f选项,加参数

start to first file 'a'

从a文件的第一行开始

1. read file a line 1 and get data 张三|000001

读取文件a的第一行,得到数据

a: $0=张三|000001

b: $1=张三

c: $2=000001

nr and fnr are the same equal to 1, and run nr=fnr block

此时,nr与fnr的值相等都为1,执行nr=fnr模块

nr==fnr{a[$2]=$0;next}

a: a[$2]=$0

a[000001]=张三|000001

b: next

next cycle and get next line data

2. read file a line 2 and get data 李四|000002

读取文件a的第二行,得到数据

a: $0=李四|000002

b: $1=李四

c: $2=000002

nr and fnr are the same equal to 2, and run nr=fnr block

此时,nr与fnr的值相等都为2,执行nr=fnr模块

nr==fnr{a[$2]=$0;next}

a: a[$2]=$0

a[000002]=李四|000002

b: next

next cycle and get next line data

end of the file a, and get next file b data

读完文件a,然后读取下一个文件b的数据

3. read file b line 1, and get data 000001|10

读取文件b的第一行,然后得到数据

a: $0=000001|10

b: $1=000001

c: $2=10

now, nr is 3 and fnr is 1, they are not eqaul

此时,nr与fnr的值不同,不执行nf=fnr模块,执行下一个模块{print a[$1] fs $2}

and didn't run nr=fnr block,

and run next block {print a[$1] fs $2}

a[$1] => a[000001] => 张三|000001

fs => |

$2 => 10

you will see the output

张三|000001|10

4. read file b line 2, and get data 000001|20

a: $0=000001|20

b: $1=000001

c: $2=20

nr is 4 and fnr is 2, they are not eqaul

and didn't run nr=fnr block,

and run next block {print a[$1] fs $2}

a[$1] => a[000001] => 张三|000001

fs => |

$2 => 20

you will see the output

张三|000001|20

cycle to read the file b

5. read file b line 3, and get data 000002|30

...

output==> 李四|000002|30

6. read file b line 4, and get data 000002|15

...

output==> 李四|000002|15

补充:

找出两个文件之间的不同部分

awk 'nr==fnr{a[$0]++} nr>fnr&&!a[$0]' 1.txt 2.txt

awk 'nr==fnr{a[$0]}nr>fnr{ if(!($1 in a)) print $0}' 1.txt 2.txt

找出两个文件之间的相同部分

awk 'nr==fnr{a[$0]++} nr>fnr&&a[$0]' 1.txt 2.txt

awk 'nr==fnr{a[$0]}nr>fnr{ if($1 in a) print $0}' 1.txt 2.txt

Logo

更多推荐