【问题标题】:Parsing extra lines in CSV file解析 CSV 文件中的额外行
【发布时间】:2013-12-10 19:03:17
【问题描述】:

我有一个 csv 文件,它的标题中有一些额外的行,最后一行是这样的:

!ReleaseDate:20131120
!id|AssetIDType|AssetID|StartDate|EndDate
ARGAAA1|CINS|P00879117|19860131|20090323
ARGAAA1|CUSIP|P00879117|19860131|20090323
......
ZIMADQ1|SEDOL|B7W9VC2|20121008|20751231
[End of File]

我想使用 Text::CSV_XS 解析它。

  1. 有没有办法摆脱第一行? (我想我可以跳过它)
  2. 将第二行作为列名(跳过第一个“!”)
  3. 阅读直到我得到 [End of File],这是一个字符串,而不是 EOF 符号?

【问题讨论】:

    标签: perl parsing csv


    【解决方案1】:

    您可以执行以下操作:

    use strict;
    use warnings;
    use Text::CSV_XS;
    
    my $csv = Text::CSV_XS->new( { binary => 1, auto_diag => 1, sep_char => '|' } );
    
    open my $fh, "<:encoding(utf8)", 'File.csv' or die "File.csv: $!";
    
    while ( my $row = $csv->getline($fh) ) {
        next if $row->[0] =~ /^!|\[/;
        print $row->[2], "\n";
    }
    
    close $fh;
    

    数据集上的输出:

    P00879117
    P00879117
    B7W9VC2
    

    如果当前行以您在第一列中找不到的字符(或一组字符)开头,则会得到next 行。

    希望这会有所帮助!

    【讨论】:

    • 这完成了我所问的大部分工作,但它不会自动读取列名(第二个问题)。
    【解决方案2】:

    有没有办法摆脱第一行? (我想我可以跳过它)

    您可能会检查以! 开头的行,或者如果您对文件格式非常有信心,则跳过第一行。

    将第二行作为列名(跳过第一行!)

    您可以使用getline 读取标题行,然后将生成的arrayref 传递给column_names,然后再使用getline_hr 读取文件的其余部分。该模块的文档提供了一个类似这样的示例:

    my @cols = @{$csv->getline($io)};
    $csv->column_names(@cols);
    while (my $row = $csv->getline_hr($io)) {
        print $row->{price}; #this assumes there is a 'price' field
    } 
    

    如果您要读取 大量 数据,可以使用 bind_columns 进行优化,同样使用模块文档中的示例。

    阅读直到我得到 [End of File]?

    如上面的代码 sn-p 所示,while 循环可以解决问题。到达文件末尾后,各种 getline 函数将返回 undef 或其他一些错误值,这将终止循环。

    【讨论】:

    • [End of File] 不是 EOF 符号,它是一个字符串。第二行有“!”在它前面签名,所以 bind_columns 可能会将它作为名称的一部分
    • @RomanHoyenko 您可以轻松根据您的任务调整 rutter 的代码。要从列名中去除前导 !,请在调用 $csv-&gt;column_names(@cols) 之前更新 @cols。你可以在while循环中检查你的魔法[End of File]字符串,如果你点击它就退出循环。
    • 我认为 $csv->getline_hr($io) 在获取 [End of File] 时会失败。我希望它在不正确的行上失败,但不在这一行上。
    • @RomanHoyenko 你试过了吗?我得到[End of File] 作为第一列的值,所有其他列都是undef
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-22
    • 1970-01-01
    • 2012-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多