Python 返回比 Linux `wc -l` 高得多的行数的代码

Python code for number of lines returning much higher number than Linux `wc -l`

当我对 Linux 中的文件(一个几百万行的 CSV 文件)执行 wc -l 时,它报告的行数低于此 Python代码显示(简单地遍历文件中的行)超过一千。会是什么原因呢?

with open(csv) as csv_lines:
    num_lines = 0
    for line in csv_lines:
        num_lines += 1
    print(num_lines)

我遇到过 wc 报告比上面少一个的情况,这在文件没有终止换行符的情况下是有意义的,因为看起来 wc 计算完整行(包括终止换行符),而此代码只计算任何行。但是相差一千多行会怎样呢?

我不太了解行结尾之类的东西,所以我可能误解了 wc 和这个 Python 代码如何计算行数,所以也许有人可以澄清一下。在 linux lines counting not working with python code 中,它表示 wc 通过计算文件中 \n 个字符的数量来工作。但是 Python 代码到底在做什么?

有没有一种方法可以调和数字上的差异,从而找出究竟是什么原因造成的?就像一种从 Python 计算行数的方法,其计数方式与 wc 相同。

文件可能是在 Linux 的不同平台上生成的,不确定是否相关。

尝试取文件的一部分并重复行数。例如:

# take first 10000 lines
head -10000 file.csv > file_head.csv

# take last 10000 lines
tail -10000 file.csv > file_tail.csv

# take first 100MB
dd if=file.csv of=file_100M.csv bs=1M count=100

既然您使用的是 print(num_lines),我假设您使用的是 Python 3.x,我以 Python 3.4.2 为例。

行数不同的原因是 open(<name>) 打开的文件将 \r\n 个字符计算为 单独 行以及 \r\n 组合(docs 通用换行符 部分)。这导致以下结果:

>>> with open('test', 'w') as f:
        f.write('\r\r\r\r')

>>> with open('test') as f:
        print(sum(1 for _ in f))
4

wc -l 给出:

$ wc -l test
0 test

\r 字符在旧的 Macintosh 系统中用作换行符。

如果您只想拆分 \n 个字符,请将 newline 关键字参数用于 open:

>>> with open('test', 'w') as f:
        f.write('\r\r\r\r')

>>> with open('test', newline='\n') as f:
        print(sum(1 for _ in f))
1

1 来自您已经提到的事实。文件中没有单个 \n 字符,因此 wc -l returns 0,并且 Python 将其计为一行。