为什么 wc 报告的文件行数与 awk 读取的记录数不同?

Why does the number of lines in a file reported by wc differ from the number of records read by awk?

当我使用 awk 计算文件中的行数时:

cat ~/.account | wc -l

...结果是:

384

但是当我使用 awk 时:

awk 'BEGIN {x = "1.02"; y = 0; } {x = x*2; y = y + 1} END {print x; print y}' ~/.account

...结果是:

8.03800926406447389928897056654e+115

385

这是为什么?

wc -l 在做什么

来自 man wc:

-l, --lines

print the newline counts

使用wc -l计算换行符的数量并且awk将输入分隔成记录由换行符分隔.

考虑这个例子:

$ echo 1 | wc -l
1
$ echo -n 1 | wc -l
0

第一个命令 (echo 1 ) 的输入是字符串 "1\n"。将 -necho 结合使用会回显 1 而末尾没有换行符 ,这使得输入只是字符串 "1"wc -l 计算输入中的换行符。在第一种情况下,有一个换行符,在第二种情况下有 none.

AWK 在做什么

AWK 将其输入分成记录,每条记录分为字段。这是 AWK 为我们所做的解析魔法的重要组成部分。

来自 The GNU AWK User's Guide(但指的是标准 AWK):

Records are separated by a character called the record separator. By default, the record separator is the newline character. This is why records are, by default, single lines.

但是如果输入以此分隔符结尾,看看会发生什么:

$ echo 1 | awk 'END{print NR}'
1
$ echo -n 1 | awk 'END{print NR}'
1

(NR是"the total number of input records read so far from all data files."的特殊变量)

每种情况下只有一条记录,即使是第一个 ("1\n") 包含换行符的记录。由于分隔符之后没有任何内容,因此它不会分隔任何内容。换句话说,如果输入以分隔符结尾,它不会在最后给出空记录。

如果您的输入文件没有以换行符字符结尾,wc -l将报告比awk的记录数少一个(NR).