awk之NR==FNR问题

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

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

下面看两个例子:

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

# awk ‘{print NR,$0}‘ file1
1 a b c d
2 a b d c
3 a c b d

#awk ‘{print FNR,$0}‘ file1
1 a b c d
2 a b d c
3 a c b d

  

2,但是对于多个文件 :

# awk ‘{print NR,$0}‘ file1 file2
1 a b c d
2 a b d c
3 a c b d
4 aa bb cc dd
5 aa bb dd cc
6 aa cc bb dd

# awk ‘{print FNR,$0}‘ file1 file2
1 a b c d
2 a b d c
3 a c b d
1 aa bb cc dd
2 aa bb dd cc
3 aa cc bb dd

  

在看一个例子关于NR和FNR的典型应用:

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

#cat a
张三|000001
李四|000002
#cat b
000001|10
000001|20
000002|30
000002|15

  

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

张三|000001|10
张三|000001|20
李四|000002|30
李四|000002|15

执行如下代码

#awk -F \| ‘NR==FNR{a[$2]=$0;next}{print a[$1]"|"$2}‘ a b

  

注释:

由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

start to first file ‘a‘
1. read file a line 1 and get data 张三|000001
A: $0=张三|000001
B: $1=张三
C: $2=000001

NR and FNR are the same equal to 1, and run NR=FNR block
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: $0=李四|000002
B: $1=李四
C: $2=000002

NR and FNR are the same equal to 2, and run NR=FNR block
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

3. read file b line 1, and get data 000001|10
A: $0=000001|10
B: $1=000001
C: $2=10

now, NR is 3 and FNR is 1, 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 => 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

时间: 2024-10-12 14:51:28

awk之NR==FNR问题的相关文章

awk中NR和FNR的区别

NR  The total number of input records seen so far. FNR The input record number in the current input file. 简单翻译: NR  表示读到的文件行数 FNR 表示读到的当前文件行数 awk中NR和FNR的区别

awk中的NR FNR

shell编程中,awk简直就是一把利器,你能够把它看成shell的一部分,也能够看成一种单独的语言,功能十分强大.今天先来说一说NR与FNR 先准备两个文件: 1.txt,内容为: user password wolf 123456 zys 123 2.txt 内容为: id user 0001 wolf 0002 xiaozhai 事实上在处理单个文件时,NR与FNR都一样.表示当前读取的行号,如运行awk '{print NR}' 1.txt 和运行 awk '{print FNR}' 1

AWK用法入门详解

简介 awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理. awk有3个不同版本: awk.nawk和gawk,未作特别说明,一般指gawk,gawk 是 AWK 的 GNU 版本. awk其名称得自于它的创始人 Alfred Aho .Peter Weinberger 和 Brian Kernighan 姓氏的首个字母.实际上 AWK

awk命令笔记

awk是一种可以处理数据.产生格式化报表的语言,功能相当强大.awk的工作方式是读取数据文件,将每一行数据视为一条记录(record),每笔记录以字段分隔符分成若干字段,然后输出各个字段的值.awk对每一条记录,都会套用一个"样式{操作}",如果该行符合样式,就执行指定的操作.样式或操作之一,可以省略.如果只有样式,表示要显示符合样式的数据行:如果只有操作,表示对每一数据行都执行该项操作. 以下是awk常用的作用格式: awk"样式"文件:把符合样式的数据行显示出来

awk 处理多个文件

awk处理多个文件的方式是:一个一个的处理. Demo1 $ cat $ cat 1.txt a 1 b 2 c 3 d 4 $ cat 2.txt b 5 c 6 d 7 e 8 $ awk '{print $0}' 1.txt 2.txt a 1 b 2 c 3 d 4 b 5 c 6 d 7 e 8 那怎么分辨当前处理的是哪一个文件呢?先看一下awk的内建变量有哪些. FILENAME: 当前输入的文件名字 FNR: 当前输入文件的记录数 NR: awk开始工作处理的总的记录数 NF: 当

awk 用法(自己笔记)

Table of Contents 1. awk简介 2. awk命令格式和选项 2.1. awk的语法有两种形式 2.2. 命令选项 3. 模式和操作 3.1. 模式 3.2. 操作 4. awk的环境变量 5. awk运算符 6. 记录和域 6.1. 记录 6.2. 域 6.3. 域分隔符 7. gawk专用正则表达式元字符 8. POSIX字符集 9. 匹配操作符(~) 10. 比较表达式 11. 范围模板 12. 一个验证passwd文件有效性的例子 13. 几个实例 14. awk编程

awk同时处理多个文件

关于awk的多文件处理: awk的数据输入有两个来源,标准输入和文件,后一种方式支持多个文件,如1.shell的Pathname Expansion方式:awk '{...}' *.txt # *.txt先被shell解释,替换成当前目录下的所有*.txt,如当前目录有1.txt和   2.txt,则命令最终为awk '{...}' 1.txt 2.txt2.直接指定多个文件: awk '{...}' a.txt b.txt c.txt ...awk对多文件的处理流程是,依次读取各个文件内容,如

那些年我用awk时踩过的坑——awk使用注意事项

由于项目经历原因,经常使用awk处理一些文本数据.甚至,我特意下载了一个windows上的awk:gawk.exe,这样在windows上也能享受awk处理数据的方便性,. 俗话说,"常在河边走,哪能不湿鞋",使用awk过程中碰上过不少坑,这里稍总结一下,希望对大家有帮助. 1 FS问题 看看这两个awk脚本: cat demo_1.txt demo_2.txt 1|2|3|4| 1|@|2|@|3|@|4|@| awk -F '|' '{print $2}' demo_1.txt;

AWK整理

处理模式: awk的处理文本和数据的方式是这样的,它逐行扫描文件,从第一行到最后一行,寻找匹配的特定模式的行,并在这些行上进行你想要的操作.如果没有指定处理动作,则把匹配的行显示到标准输出(屏幕),如果没有指定模式,则所有被操作所指定的行都被处理. 组成部分: 处理输入前将做的处理BEGIN, 处理输入过程将做的处理, 处理输出完成后做的处理END 指定分隔符: awk 'BEGIN { FS = ":" }  {print $1}'  /etc/passwd awk -F:  '{p