【问题标题】:Perl parsing the csv filePerl解析csv文件
【发布时间】:2012-09-10 05:24:10
【问题描述】:

我只是第一次尝试读取 .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 记录,即名称、位置、公司名称,那我该怎么办?

谢谢

【问题讨论】:

  • 解析文件 = 阅读/解释整个事情。逐行让您可以随时停止,因为一次只处理一行。至于你的其他问题——一旦数据被人读取/解析,你可以对返回的数组做任何你想做的事情。

标签: perl


【解决方案1】:

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,但这完全是一个不同的话题。

【讨论】:

    【解决方案2】:

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

    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。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-14
      • 2021-01-03
      • 1970-01-01
      • 2016-01-22
      • 2012-06-08
      • 2016-12-16
      • 2021-02-28
      • 2019-05-19
      相关资源
      最近更新 更多