0

我只是第一次尝试读取 .csv 文件。我浏览了以下链接:

http://metacpan.org/pod/Text::CSV_XS#Reading-a-CSV-file-line-by-line

我毫无疑问,如果你愿意,你可以告诉我这是个愚蠢的问题,但我不知道,为什么我无法弄清楚 perl 究竟是如何读取 csv 文件的 :(

所以,我的疑问是:

第一个问题

逐行读取csv文件和解析文件有什么区别。

我有一个简单的程序,我正在逐行读取 csv 文件。下面是我的程序:

#!/usr/bin/perl -w
use strict;
use Text::CSV;
use Data::Dumper;

my $csv=Text::CSV->new( );
my $my_file="test.csv";
open(my $fl,"<",$my_file) or die"can not open the file $!";
#print "$ref_list\n";

while(my $ref_list=$csv->getline($fl))
{
 
print "$ref_list->[0]\n";
} 

以下是 csv 文件中的数据:

"Emp_id","Emp_name","Location","Company"
102713,"raj","Banglore","abc"
403891,"Rakesh","Pune","Infy"
530201,"Kiran","Hyd","TCS"
503110,"raj","Noida","HCL"

第二个问题:

如果我想获得特定的 Emp_id 以及 Location 那么我该如何继续。

第三个问题:

如果我只想要 102713 ,530201,503110 Emp 记录,即名称、位置、公司名称,那我该怎么办?

谢谢

4

2 回答 2

3

CSV 文件可以很好地表示文本格式的表格数据,但它不适合内存中的表示。正因为如此,我们必须创建一个适当的代表。一种这样的表示是散列:

my $hashref = {
   Emp_Id   => ...,
   Emp_name => ...,
   Location => ...,
   Company  => ...,
};

如果标题行在数组@header中,我们可以使用以下方法创建此哈希:

my @header = ...;
my @row = @{$csv->getline($fl)}; # turn the arrayref into an array
my $hashref = {};
for my $i (0..$#header) {
  $hashref->{$header[$i]} = $row[$i];
}
# The $hashref now looks as described above

然后我们可以创建使用 id 值作为键的查找哈希。所以%lookup看起来像这样:

my %lookup = (
   102713 => $hashref_to_first_line,
   ...,
);

我们通过做填充它

$lookup{$row[0]} = $hashref;

在上述循环之后。然后我们可以访问某个 hashref

my $a_certain_id_hashref = $lookup{102713};

或直接访问某些元素

my $a_certain_id_location = $lookup{102713}{Location};

如果键不存在,这些查找应该返回undef

如果 CSV 文件太大,这可能会导致 perl 内存不足。在这种情况下,散列应该是tied 到文件,但这完全是一个不同的主题。

于 2012-09-10T05:52:02.287 回答
0

这是解决您的第二个问题和第三个问题的一部分的另一个选项:

use Modern::Perl;
use Text::CSV;

my @empID = qw/ 102713 530201 503110 /;

my $csv = Text::CSV->new( { binary => 1 } )
  or die 'Cannot use CSV: ' . Text::CSV->error_diag();

my $my_file = "test.csv";
open my $fl, '<', $my_file or die "can not open the file $!";

while ( my $ref_list = $csv->getline($fl) ) {

    if ( $ref_list->[0] ~~ @empID ) {
        say "Emp_id: $ref_list->[0] is Location: $ref_list->[2]";
    }
}

$csv->eof or $csv->error_diag();
close $fl;

输出:

Emp_id: 102713 is Location: Banglore
Emp_id: 530201 is Location: Hyd
Emp_id: 503110 is Location: Noida

该数组@empID包含您感兴趣的 ID。在while循环中,使用智能匹配运算符 (Perl v5.10+) 检查每个 Emp_id 以查看它是否在 ID 列表中。如果是,则打印 Emp_id 及其对应的 Location。

于 2012-09-10T06:31:35.320 回答