使用Perl读取大量CSV文件的最佳方法是什么?

时间:2010-02-01 00:43:02

标签: perl file csv

要求

  • 我有一个非常大的CSV文件要阅读。 (约3 GB)
  • 我不需要所有记录,我的意思是,我们可以使用一些条件,例如,如果第3个CSV列内容为“XXXX”且第4列为“999”。

问题: 我可以使用这些条件来改善读取过程吗?如果是这样,我怎么能用Perl做到这一点?

我在你的回答中需要一个例子(Perl Script)。

5 个答案:

答案 0 :(得分:13)

这是一个解决方案:

#!/usr/bin/env perl
use warnings;
use strict;
use Text::CSV_XS;
use autodie;
my $csv = Text::CSV_XS->new();
open my $FH, "<", "file.txt";
while (<$FH>) {
    $csv->parse($_);
    my @fields = $csv->fields;
    next unless $fields[1] =~ /something I want/;
    # do the stuff to the fields you want here
}

答案 1 :(得分:5)

使用Text::CSV

答案 2 :(得分:5)

您的a)问题已经回答了几次,但b)尚未得到解决:

  

我的意思是,我不需要所有记录   我们有一些条件   可以使用,例如,如果第三个CSV   列内容有'XXXX'和第4   列有'999'。我可以用这些吗?   条件,以改善阅读   过程

没有。你怎么知道第三个CSV列是否包含'XXXX'或者第四个是'999'而没有先读取该行? (DBD :: CSV允许您将其隐藏在SQL WHILE子句后面,但是,因为CSV是未编入索引的数据,所以它仍然需要读取每一行以确定哪个匹配条件,哪个不匹配。)

几乎可以使用行的内容来跳过读取部分文件的唯一方法是,如果它包含告诉您的信息1)“跳过此行之后的部分”和“2)”继续读取字节offset nnn“。

答案 3 :(得分:4)

Text::CSV模块是一个很好的解决方案。另一个选项是DBD::CSV模块,它提供了稍微不同的界面。如果您正在开发必须访问来自不同形式的数据库(包括关系数据库和逗号分隔的文本文件)的数据的应用程序,则DBI接口非常有用。

以下是一些示例代码:

#!/usr/bin/perl

use strict;
use warnings;
use DBI;

$dbh = DBI->connect ("DBI:CSV:f_dir=/home/joe/csvdb") 
    or die "Cannot connect: $DBI::errstr";

$sth = $dbh->prepare ("SELECT id, name FROM info.txt WHERE id > 1 ORDER by id");
$sth->execute;

my ($id,$name);
$sth->bind_columns (\$id, \$name);
while ($sth->fetch) {
    print "Found result row: id = $id, name = $name\n";
}
$sth->finish;

我将使用Text :: CSV执行此任务,除非您计划与其他类型的数据库交谈,但在Perl TIMTOWDI中,它有助于了解您的选项。

答案 4 :(得分:3)

使用像Text :: CSV这样的模块,但是,如果你知道你的数据没有嵌入的逗号及其简单的CSV格式,那么迭代文件的简单while循环就足够了

while (<>){
  chomp;
  @s = split /,/;
  if ( $s[2] eq "XXXX" && $s[3] eq "999" ){
    # do something;
  } 
}
相关问题