什么是 NR 和 FNR,“NR==FNR”意味着什么?
Posted
技术标签:
【中文标题】什么是 NR 和 FNR,“NR==FNR”意味着什么?【英文标题】:What are NR and FNR and what does "NR==FNR" imply? 【发布时间】:2015-12-05 13:26:21 【问题描述】:我正在学习使用awk
进行文件比较。
我找到了如下语法,
awk 'NR==FNRa[$1];next$1 in aprint $1' file1 file2
我不明白NR==FNR
在这有什么意义?
如果我尝试使用FNR==NR
,那么我也会得到相同的输出吗?
它到底是做什么的?
【问题讨论】:
见Two-file Processing
backreference.org/2010/02/10/idiomatic-awk
【参考方案1】:
在 awk 中,FNR
指的是当前文件中的记录号(通常是行号),NR
指的是总记录号。运算符==
是一个比较运算符,当两个周围的操作数相等时返回true。
这意味着条件NR==FNR
仅适用于第一个文件,因为FNR
在每个文件的第一行重置回1,但NR
继续增加。
此模式通常用于仅对第一个文件执行操作。块内的next
表示跳过任何其他命令,因此它们仅在第一个以外的文件上运行。
条件FNR==NR
比较与NR==FNR
相同的两个操作数,因此其行为方式相同。
【讨论】:
"=" 有时用于测试相等性,有时用于进行分配。如果使用双等号进行分配,则 FNR==NR 将不同于 NR==FNR。所以对于不熟悉 awk 的人,比如这个提问者,问他们是否相同似乎是合理的。 @ToddWalton 好点!又如:a='3x'; if [[ $a == 3* ]]; then echo yes; fi
和==
两边不能切换。
@WalterA 是的,这是真的(至少在 Bash 中)。您是否建议对我的回答进行改进?
不,你的回答很好。我真的很想看到社区同样喜欢我们的答案。我们使用不同的风格,两者都被认为非常有帮助。我刚刚给了你一个赞成票,所以目前我们的赞成票数量相同。【参考方案2】:
在 file2 中查找也在 file1 中的键(行的第一个字)。 第 1 步:用文件 1 的第一个单词填充数组 a:
awk 'a[$1];' file1
第 2 步:在同一命令中填充数组 a 并忽略文件 2。为此,请使用当前输入文件的数量检查到目前为止的记录总数。
awk 'NR==FNRa[$1]' file1 file2
第 3 步:在解析文件 1 时忽略 之后可能发生的操作
awk 'NR==FNRa[$1];next' file1 file2
第4步:在数组a中找到file2的键
awk 'NR==FNRa[$1];next $1 in aprint $1' file1 file2
【讨论】:
这个单行的精彩删除。第 1 步中的分号是必须的吗? @TomaszGandor 步骤 1 中不需要分号。我本可以在步骤 3 中添加它,但;next
是一个奇怪的添加(例如添加 next
并在步骤 3 中需要分号)。您可以使用awk 'a[$1] END for (k in a) print "a[k]=" k ' file1
测试第 1 步。【参考方案3】:
在awk手册中查找NR
和FNR
,然后问自己以下示例中NR==FNR
的条件是什么:
$ cat file1
a
b
c
$ cat file2
d
e
$ awk 'print FILENAME, NR, FNR, $0' file1 file2
file1 1 1 a
file1 2 2 b
file1 3 3 c
file2 4 1 d
file2 5 2 e
【讨论】:
是否也可以打印正在处理的文件的编号?有内置变量吗? (我知道我们可以为此创建一个变量,并在每次 NR 为 1 时递增它) 在 GNU awk 中,该变量为ARGIND
,否则您可以使用 FNR==1 print ++file_nr
。
我没有问任何问题,我展示了如何获得 OP 问题的答案。
这应该是“答案”。它清晰简洁,通过一个任何人都可以遵循的简单示例进行说明,并且不关心不精确的措辞。做得好! .
我将支持上述评论。这太棒了。【参考方案4】:
有awk
内置变量。
NR
- 它给出了处理的记录总数。
FNR
- 它给出每个输入文件的记录总数。
【讨论】:
【参考方案5】:假设您有文件 a.txt 和 b.txt
cat a.txt
a
b
c
d
1
3
5
cat b.txt
a
1
2
6
7
记住 NR 和 FNR 是 awk 的内置变量。 NR - 给出处理的记录总数。 (在这种情况下,在 a.txt 和 b.txt 中) FNR - 给出每个输入文件的总记录数(a.txt 或 b.txt 中的记录)
awk 'NR==FNRa[$0];if($0 in a)print FILENAME " " NR " " FNR " " $0' a.txt b.txt
a.txt 1 1 a
a.txt 2 2 b
a.txt 3 3 c
a.txt 4 4 d
a.txt 5 5 1
a.txt 6 6 3
a.txt 7 7 5
b.txt 8 1 a
b.txt 9 2 1
让我们添加“下一个”以跳过第一个匹配 NR==FNR
在 b.txt 和 a.txt 中
awk 'NR==FNRa[$0];nextif($0 in a)print FILENAME " " NR " " FNR " " $0' a.txt b.txt
b.txt 8 1 a
b.txt 9 2 1
在 b.txt 中但不在 a.txt 中
awk 'NR==FNRa[$0];nextif(!($0 in a))print FILENAME " " NR " " FNR " " $0' a.txt b.txt
b.txt 10 3 2
b.txt 11 4 6
b.txt 12 5 7
awk 'NR==FNRa[$0];next!($0 in a)' a.txt b.txt
2
6
7
【讨论】:
以上是关于什么是 NR 和 FNR,“NR==FNR”意味着什么?的主要内容,如果未能解决你的问题,请参考以下文章