wc -l如何工作?


11

我必须阅读一个大文件,在开始阅读它之前,我需要知道文件中的总行数(以百万为单位)。

我已经实现了很多解决方案,并且找到了一个。但是在搜索过程中,我一直在考虑如何wc -l工作。我在Google上找不到任何东西。

尽管我已经找到解决问题的方法,但是我仍然想知道wc -l它是如何工作的,因为它可以在几秒钟内用9200万行来计算文件的行数!

怎么样?


Answers:


20

它读取整个文件并计算行尾数。计算行尾真的很便宜;大部分时间都花在读取文件上。如果文件碰巧(主要是)在缓冲区缓存中,那也将很便宜。否则,将取决于文件存储的速度。

换句话说,没有魔术。


它读取整个文件并计算行尾数?为了到达行尾,它基本上不是读取整行直到行尾吗?那将意味着它读取了整个文件,对吗?
detraveller

@detraveller:是的,它读取了整个文件,就像我说的那样。它不会逐行或一次全部读取,但会读取每个字符并计算其中多少个字符是行尾字符。
rici

7

WC只是以原始字节的块读取文件(最好是文件所在的基础文件系统的自然块大小的倍数)。
然后,它只扫描缓冲区,计算行尾字符。(它还计算空格,制表符,换页符和其他特殊字符,以防万一您需要除-l输出之外的其他信息。)

从磁盘读取是速度方面最昂贵的部分。与之相比,缓冲区的扫描花费的时间可以忽略不计。

假设您有9000万行,平均每行100个字符。
那是大约9.000.000.000个字符或大约860 MB。
带有SATA-3Gb / s驱动器的体面的PC将在10秒内完成此操作。即使在相对较慢的文件系统上,同时又有其他活动在进行。
具有某些性能调整和优化的文件系统的快速计算机可以在5秒内完成此操作,即使无需诉诸SATA-6G和SSD驱动器。


它只是扫描缓冲区并计算行尾(\n)字符-“ -l,--lines打印换行符\ n \”-摘自wc.c
Rahul Patil

@RahulPatil大多数实现不只是计算换行符而已。请参阅上面的顶部注释中提到的示例。这就是Linux核心实用程序中使用的wc的来源。
Tonny

是的..我已经看到了..我只是提到,因为,关于wc -l..抱歉的问题……
Rahul Patil

3

欢迎来到自由软件的世界。您可以随时查看源代码

尽管我必须承认我不是C程序员,所以我不是一个真正可以为您解释代码的人(我自己感到困惑)。

我知道的是,由于wc不会打开文件本身,而是要求操作系统执行此操作,因此这在很大程度上取决于操作系统,当然还取决于文件的存储方式。除此之外,我希望必须有正确的编程习惯,例如不要尝试一次读取整个文件,等等。


您说“不尝试一次读取整个文件”是什么意思?
detraveller

我的意思是将文件加载到内存,例如单个字符串/数组。在Perl社区中,这被称为“拖尾”,这是一种快速而肮脏的解决方案,当您知道将要读取几行内容时可以,但是一次将真正的大文件馈送到内存中并不是一个好主意。
Alois Mahdal

1
另一方面,您可以读取例如64 KiB,计数换行符并丢弃它,然后重复...这样,无论文件有多大,您最多将吃掉超过64 KiB的内容。(当您意识到换行符可以有2个字节并因此分成2个块时,这会变得不那么容易;现在
这才

不太重要,但是:“因为wc不会打开文件本身,而是要求OS进行操作” –不确定您的意思,但是我怀疑这是正确的。当然,它本身就是在读取所有字符。
Arjan

2
@Arjan尽管确实正确:除了嵌入式系统之外,程序几乎无法真正完成自身的读取工作,而内核和OS的全部意义在于它可以为它们完成工作。实际上,open(),close(),read()(无论是Linux,Windows,套接字还是文件)都是系统调用,实际程序不了解内部工作原理。
Alois Mahdal
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.