2010-10-03 33 views
-1

我试图下载一个.csv文件到一个数组中,然后逐行解析每一列的Text :: CSV。我有以下几点:如何解析用Perl下载的CSV数据?

my @file = get("http://www.someCSV.com/file.csv") or warn $!; 

my $CSV = Text::CSV->new(); 
$CSV->sep_char (','); 

for (@file) { 

    $CSV->parse($_) or warn $!; 

     my @columns = $CSV->fields(); 
     print $columns[0] . "\n"; 
} 

而不是下载文件,保存它,然后它啜成一个文件句柄,我认为这将是更有效地只是把CSV文件到一个数组中,并从那里解析。但是,上面的代码不起作用,我不明白为什么。我收到“警告:test.pl出错了”;不是很有帮助,至少可以说。

这是更多的学习。我不需要这样做,但它只是在烦扰我为什么我无法将Text :: CSV与数组一起使用。

+0

什么是get函数?从'LWP :: UserAgent'?你确认'@ file'的元素是来自'file.csv'的行吗? – 2010-10-03 22:56:31

+0

我假设'get'来自'LWP :: UserAgent'?一般来说,你应该在代码中使用'使用XXX'部分。一个'get'与另一个不是一样的...... – dawg 2010-10-03 22:58:35

+1

不太有用的“错误的东西”错误是因为你实际上没有告诉perl给你一个有用的错误。 '$!'只在系统调用失败时设置,对模块的调用通常不会设置'$!'。 “警告”或“死亡”包括描述性文本以及任何可应用的错误变量时,总是一种好的做法。像'......或警告'失败';''或'警告'解析失败';'。越具描述性越好。 '$!'被忽略,因为它可能不会被get或parse设置(但是检查他们的文档来验证)。在拉夫的回答中,您仍然希望将其包含在电话中打开 – 2010-10-04 15:42:39

回答

11

我假设你在那里使用LWP::Simpleget函数。这不会返回响应主体的行列表,而是返回包含响应主体的字符串。所以刚开始,你可能是指:

my $content = get($uri); 

现在你可以去逐行读取该行,路过每行Text::CSV小号parse方法。这在某些情况下可能会起作用,但由于CSV文件可能包含嵌入的换行符,因此它不会很可靠。

取而代之的是,让Text::CSV通过传递一个它自己可以读取的文件句柄来计算输入中的一行。为此,不需要在本地保存文件。你可以打开一个字符串的句柄:

open my $fh, '<', \$content or die $!; 

my $csv = Text::CSV->new({ sep_char => ',' }); 
while (my $row = $csv->getline($fh)) { 
    my @fields = @{ $row }; 
    ... 
} 
+0

当您遇到这些问题时,请在继续下一步之前查看您拥有的数据。 – 2010-10-05 17:34:09