如何使用Perl计算大型CSV文件中行数?

3

我在工作中需要在Windows环境下使用Perl,并且需要能够找到一个大约1.4GB的csv文件包含的行数。有什么方法可以在最小的资源浪费下完成这个任务吗?

谢谢。

PS:必须在Perl脚本内完成此操作,我们不允许在系统上安装任何新模块。


1
“不允许安装新模块”通常是一个概念上的谬论。http://stackoverflow.com/questions/755168/perl-myths/755179#755179 - Kent Fredric
6个回答

14

你是指行还是列?单元格可能包含换行符,这会增加文件的行数,但不是行数。如果可以保证没有单元格包含换行符,则只需使用Perl FAQ中的技术。否则,您需要使用像Text::xSV这样的适当的CSV解析器。


1
你应该修改你的问题,因为其他所有评论都只是在进行行数统计。 - jiggy
+1,好观点,但也值得一提的是,并没有“官方”的CSV格式——只有一系列松散定义、有些不兼容的格式,它们在如何引用逗号和单元格内是否允许换行等方面存在分歧。许多工具假定1行==1行。 - j_random_hacker

9

是的,不要使用perl。

相反,使用简单的行数计算工具; wc.exe

它是从Unix原始程序移植而来的一组Windows实用程序之一。

http://unxutils.sourceforge.net/

例如;

PS D:\> wc test.pl
     12      26     271 test.pl
PS D:\>

这里的12指的是行数,26是单词数,271是字符数。

如果你真的必须使用perl;

D:\>perl -lne "END{print $.;}" < test.pl
12

1
当然,在*nix上,wc是可行的选择,因为它已经安装好了。但是,下载一个单独的可执行文件来完成一些只需要短小的Perl代码的事情真的值得吗? - j_random_hacker
是的,因为Cygwin对于任何Windows开发环境来说都是必备的。 - KenE
1
这不是Cygwin,但仍然是必备工具。在文件中计算行数是非常常见的活动,因此拥有此实用程序绝对是值得的。 - Ed Guiness
@KenE: 这是讽刺吗?FTR UnxUtils 不基于 Cygwin。 - j_random_hacker
@Manni:或者想象一下,如果他只被允许在着火的锁定算盘上使用COBOL。 :-P - j_random_hacker
显示剩余6条评论

4
perl -lne "END { print $. }" myfile.csv

这只会一次读取一行,所以除非每行都非常长,否则不会浪费任何内存。

行并不等同于 CSV 行。例如,考虑到带有换行符的字段。 - brian d foy
@brian:没错。但同样正确的是,处理包含换行符的字段的CSV文件注定是令人痛苦的,因为在工具之间没有普遍协议来规定这些内容应该如何编码 - 不幸的是,CSV不是一个“标准”。 - j_random_hacker

3
这个一行代码可以处理行内的换行符:
  1. Considering lines with an odd number of quotes.
  2. Considering that doubled quotes is a way of indicating quotes within the field.
  3. It uses the awesome flip-flop operator.

    perl -ne 'BEGIN{$re=qr/^[^"]*(?:"[^"]*"[^"]*)*?"[^"]*$/;}END{print"Count: $t\n";}$t++ unless /$re/../$re/'
    
考虑以下事项:
  • wc 不适用于计算 CSV 行数,它非常擅长计算文本行数。
  • 应该安装或者努力安装Text::CSV 或类似的标准包来进行正确处理。
  • 不过这也许能够帮到你。


编辑: 我忘了这是 Windows 系统:

perl -ne "BEGIN{$re=qr/^[^\"]*(?:\"[^\"]*\"[^\"]*)*?\"[^\"]*$/;}END{print qq/Count: $t\n/;};$t++ unless $pq and $pq = /$re/../$re/;"

奇怪的是,The Broken OS的shell将&&解释为操作系统的条件执行,我无法改变它的想法!!如果我进行转义,它只会将其传递给perl。


0

edg的答案值得点赞,另一个选择是安装cygwin在Windows上获取wc和其他一些方便的工具。


IME,Cygwin 添加了太多的复杂性,除非你想运行一个伪 Unix 环境。MinGW 和 MSYS 提供了一个更轻量级的系统,非常适合软件开发。对于简单的命令行工具,GnuWin32 提供了一系列良好的工具选择,安装简单,对系统影响小。 - daotoad
谢谢你的建议 - 我会有时间试试看! - KenE
wc不是答案,因为它计算的是行数,而不是CSV行。请参考Axeman的回答。 - brian d foy

-1

我当时很蠢,脚本中简单的方法是:

open $extract, "<${extractFileName}" or die ("Cannot read row count of $extractFileName");
$rowCount=0;    
while (<$extract>)
{
    $rowCount=$rowCount+1;
}

close($extract);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接