什么是awk中的"NR == FNR"?

Ami*_*mit 57 unix linux awk

我正在学习文件比较awk.

我找到了如下的语法,

awk 'NR==FNR{a[$1];next}$1 in a{print $1}' file1 file2
Run Code Online (Sandbox Code Playgroud)

我无法理解这NR==FNR在什么意义?如果我尝试,FNR==NR那么我也得到相同的输出?

到底是做什么的?

Tom*_*ech 66

在awk中,FNR指的是当前文件中的记录号(通常是行号)并NR引用总记录号.运算符==是一个比较运算符,当两个周围的操作数相等时返回true.

这意味着条件NR==FNR仅适用于第一个文件,因为FNR每个文件的第一行重置为1,但NR会继续增加.

此模式通常用于仅对第一个文件执行操作.在next块内是指任何进一步的命令被跳过,所以它们仅在比所述第一其他文件运行.

该条件FNR==NR比较了相同的两个操作数NR==FNR,因此它的行为方式相同.

  • “ =“有时用于测试相等性,有时用于进行赋值。如果将双等号用于分配,则FNR == NR将与NR == FNR不同。因此,对于像awk这样不熟悉awk的人,询问他们是否相同似乎是合理的。 (2认同)

Wal*_*r A 55

在file2中查找也在file1中的键(第一行).
第1步:使用文件1的第一个单词填充数组a:

awk '{a[$1];}' file1
Run Code Online (Sandbox Code Playgroud)

步骤2:在同一命令中填充数组a并忽略文件2.为此,使用当前输入文件的编号检查到目前为止的记录总数.

awk 'NR==FNR{a[$1]}' file1 file2
Run Code Online (Sandbox Code Playgroud)

步骤3:忽略}解析文件1时可能出现的操作

awk 'NR==FNR{a[$1];next}' file1 file2 
Run Code Online (Sandbox Code Playgroud)

步骤4:在数组a中找到file2的打印键

awk 'NR==FNR{a[$1];next} $1 in a{print $1}' file1 file2
Run Code Online (Sandbox Code Playgroud)

  • 这个单线的辉煌删除.步骤1中的分号是否必要? (2认同)
  • @TomaszGandor 在第 1 步中不需要分号。我可以在第 3 步中添加它,但是 `;next` 是一个奇怪的添加(比如添加 `next` 并且在第 3 步中需要分号)。您可以使用 `awk '{a[$1]} END { for (k in a) { print "a[k]=" k } }' file1` 来测试步骤 1。 (2认同)

Ed *_*ton 33

查看NRFNR在awk手册中,然后问自己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
Run Code Online (Sandbox Code Playgroud)

  • 这应该是“答案”。它清晰简洁,通过任何人都可以遵循的简单示例进行说明,并且不会使用不精确的措辞。做得好!。 (3认同)

sat*_*sat 10

awk内置变量.

NR - 它给出了处理的记录总数.

FNR - 它给出每个输入文件的总记录数.


Don*_*mba 8

假设你有文件a.txt和b.txt

cat a.txt
a
b
c
d
1
3
5
cat b.txt
a
1
2
6
7
Run Code Online (Sandbox Code Playgroud)

请记住NR和FNR是awk内置变量.NR - 提供处理的记录总数.(在这种情况下,在a.txt和b.txt中)FNR - 给出每个输入文件的记录总数(记录在a.txt或b.txt中)

awk 'NR==FNR{a[$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
Run Code Online (Sandbox Code Playgroud)

让我们添加"下一个"以跳过与NR == FNR匹配的第一个

在b.txt和a.txt中

awk 'NR==FNR{a[$0];next}{if($0 in a)print FILENAME " " NR " " FNR " " $0}' a.txt b.txt
b.txt 8 1 a
b.txt 9 2 1
Run Code Online (Sandbox Code Playgroud)

在b.txt中但不在a.txt中

 awk 'NR==FNR{a[$0];next}{if(!($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==FNR{a[$0];next}!($0 in a)' a.txt b.txt
2
6
7
Run Code Online (Sandbox Code Playgroud)