【问题标题】:Skip bad CSV lines in Perl with Text::CSV使用 Text::CSV 在 Perl 中跳过错误的 CSV 行
【发布时间】:2015-02-06 13:07:55
【问题描述】:

我有一个基本上仍在测试中的脚本。 我想使用 Text CSV 来分解每小时转储的大量 CSV 文件。

这些文件可能非常大且质量不一致。 有时我会得到奇怪的字符或数据,但通常的问题是行会停止。

"Something", "3", "hello wor

封闭式报价是我最大的障碍。脚本只是中断。错误转到stderr,我的while循环被打破了。

While (my $row = $csv->getline($data))

我得到的错误是......

# CSV_PP ERROR: 2025 - EIQ - Loose unescaped escape

我似乎无法对此进行任何类型的错误处理。如果我启用 allow_loose_escapes,我得到的只是很多错误,因为它将后续的新行视为同一行的一部分。

【问题讨论】:

    标签: perl csv


    【解决方案1】:

    允许松散的逃跑不是答案。正如您也提到的,它只会使您的程序忽略错误并尝试将虚线与其他行合并。相反,您可以尝试发现问题,并检查您的 $row 是否已定义:

    use strict;
    use warnings;
    use Text::CSV;
    use feature 'say';
    
    my $csv = Text::CSV->new({
            binary  => 1,
            eol => $/,
        });
    
    while (1) {
        my $row = $csv->getline(*DATA);
        $csv->eof and last; 
        if (defined $row) {
            $csv->print(*STDOUT, $row);
        } else {
            say "==" x 10;
            print "Bad line, skipping\n";
            say $csv->error_diag();
            say "==" x 10;
        }
    }
    
    
    __DATA__
    1,2,3,4
    a,b,c,d
    "Something", "3", "hello wor
    11,22,33,44
    

    对我来说这个输出:

    1,2,3,4
    a,b,c,d
    ====================
    Bad line, skipping
    2034EIF - Loose unescaped quote143
    ====================
    11,22,33,44
    

    如果你想保存虚线,可以通过$csv->error_input()访问,例如:

    print $badlines $csv->error_input();
    

    【讨论】:

    • while (!$csv->eof) { ... } 会比无限循环更好吗?
    • @Demnogonis 似乎 Text::CSV 的 eof 与 Perl 的不同,因为它检查文件的结尾 读取该行之后,而不是之前。
    • 作为一个 Perl 新手,我必须弄清楚如何在 5.8.9 中让它工作,但它的性能非常好。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2016-12-16
    • 1970-01-01
    • 2019-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多