通常我wc -l
用来计算文件的行数。但是,对于具有 5*10^7 行的文件,我只得到 10^7 作为答案。我已经尝试了这里提出的所有内容:
如何计算文档中的行数?
但这比wc -l
.
还有其他选择吗?
任何认真对待速度线计数的人都可以创建自己的实现:
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#define BUFFER_SIZE (1024 * 16)
char BUFFER[BUFFER_SIZE];
int main(int argc, char** argv) {
unsigned int lines = 0;
int fd, r;
if (argc > 1) {
char* file = argv[1];
if ((fd = open(file, O_RDONLY)) == -1) {
fprintf(stderr, "Unable to open file \"%s\".\n", file);
return 1;
}
} else {
fd = fileno(stdin);
}
while ((r = read(fd, BUFFER, BUFFER_SIZE)) > 0) {
char* p = BUFFER;
while ((p = memchr(p, '\n', (BUFFER + r) - p))) {
++p;
++lines;
}
}
close(fd);
if (r == -1) {
fprintf(stderr, "Read error.\n");
return 1;
}
printf("%d\n", lines);
return 0;
}
用法
a < input
... | a
a file
例子:
# time ./wc temp.txt
10000000
real 0m0.115s
user 0m0.102s
sys 0m0.014s
# time wc -l temp.txt
10000000 temp.txt
real 0m0.120s
user 0m0.103s
sys 0m0.016s
*-O3
使用 GCC 4.8.2 在带有 AVX 和 SSE4.2 的系统上本地 编译的代码。
你可以试试sed
sed -n '$=' file
说要打印行号,而=
美元说只在最后一行打印。-n
说不要做太多其他事情。
或者这是 Perl 中的一种方法,将其保存为wc.pl
并执行chmod +x wc.pl
:
#!/usr/bin/perl
use strict;
use warnings;
my $filename = <@ARGV>;
my $lines = 0;
my $buffer;
open(FILE, $filename) or die "ERROR: Can not open file: $!";
while (sysread FILE, $buffer, 65536) {
$lines += ($buffer =~ tr/\n//);
}
close FILE;
print "$lines\n";
像这样运行它:
wc.pl yourfile
基本上,它一次以 64kB 的块读取您的文件,然后利用tr
在要求它删除所有换行符后返回它所做的替换次数的事实。
尝试使用 nl 看看会发生什么......
awk
您可以使用以下方法获取行数
awk 'END {print NR}' names.txt
(或)使用while .. do .. done
bash 循环结构,如
CNT=0; while read -r LINE; do (( CNT++ )); done < names.txt; echo $CNT
取决于您如何打开文件,但可能从 STDIN 读取它会得到修复:
wc -l < file