什么是 NR 和 FNR? “ NR = = FNR”意味着什么?

我正在学习使用 awk文件比较。

我找到了如下的语法,

awk 'NR==FNR{a[$1];next}$1 in a{print $1}' file1 file2

我不明白 NR==FNR在这里的意义是什么? 如果我尝试与 FNR==NR然后我也得到相同的输出?

它到底是做什么的?

164123 次浏览

awk内置的变量。

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

FNR - It gives the total number of records for each input file.

不好意思,

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

This means that the condition NR==FNR is only true for the first file, as FNR resets back to 1 for the first line of each file but NR keeps on increasing.
此模式通常仅用于对第一个文件执行操作。

The next inside the block means any further commands are skipped, so they are only run on files other than the first.

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

在 awk 手册中查找 NRFNR,然后问自己在下面的例子中 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

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

awk '{a[$1];}' file1

步骤2: 在同一命令中填充数组 a 并忽略文件2。为此检查记录的总数,直到现在与当前输入文件的数量。

awk 'NR==FNR{a[$1]}' file1 file2

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

awk 'NR==FNR{a[$1];next}' file1 file2

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

awk 'NR==FNR{a[$1];next} $1 in a{print $1}' file1 file2

假设您的文件是 a.txt 和 b.txt

cat a.txt
a
b
c
d
1
3
5
cat b.txt
a
1
2
6
7

Keep in mind 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

让 Add“ next”跳过与 NR = = FNR 匹配的第一个

在 b.txt 和 atxt 中

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

在 b.txt 里,但不是在 atxt 里

 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

下面是您感兴趣的伪代码。

NR = 1
for (i=1; i<=files.length; ++i) {
line = read line from files[i]
FNR = 1
while (not EOF) {
columns = getColumns(line)


if (NR is equals to FNR) { // processing first file
add columns[1] to a
} else { // processing remaining files
if (columns[1] exists in a) {
print columns[1]
}
}
NR = NR + 1
FNR = FNR + 1
line = read line from files[i]
}
}