【问题标题】:Parse::CSV, parsing file without headersParse::CSV,解析没有标题的文件
【发布时间】:2018-10-10 18:56:47
【问题描述】:

我得到的数据是来自 mysql 数据库的转储,其中一些文件缺少列标题。

当我尝试获取一行时,说 Dumper $parser->fetch; 在没有列标题的文件上返回 undefined。我已经完成了 if (-e $file) 并且它看到了该文件。我也试过了

名字 => 1

names => ['id', 'description']

两次输出都是 undef,尽管对于后者 $parser->names 确实输出了 iddescription(名称,而不是列值)。

我是否正确分配了列名?如果是,为什么返回 undefined?

#!/usr/bin/perl

use v5.24.3;
use strict;
use warnings;

# Modules
use Data::Dump;                                     # dd \%hash
use Data::Dumper;                                   # say Dumper(\%hash)                        
use Spreadsheet::ParseXLSX;
use Text::CSV_XS;
use Parse::CSV;

my $path    = './path/to/data/';
my $vendor  = 'fwd';
my $ext     = '.csv';
my @f       = (
    'spring_categories',
    'prod_descriptions',
    'feature_bullets',
    'category_mapping'
);
my $file = $path . $vendor . '/' . $f[1] . $ext;

my $parser = Parse::CSV->new(
    "file"        => $file,                                       
    "names"       => ['id', 'description'],
    "csv_attr"    => {
        "sep_char" => ',',
        "quote_char" => "'"
    }
);

# Not triggering error
if ( $parser->errstr )
{
    say "There was an error";
}
else
{
    say $parser->names;             # outputs | iddescription
    say Dumper $parser->fetch;      # outputs | $VAR1 = undef

    # Doesn't reach while
    while ( my $value = $parser->fetch )
    {
        say Dumper $value;
        say $parser->row;

        # my @names = $parser->names;
        # dd \@names;
        # say $names[0];

        die;
    }

这是我在没有机密数据的情况下共享的临时测试文件,对我来说也有同样的问题。

4732947234,"Lorem ipsum dolor sit amet, consectetur adipiscing elit"
6732947274,"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo"
7657657274,Nemo enim ipsam voluptatem quia voluptas 
3993007274,magnam aliquam quaerat voluptatem
2449049474,"laboriosam, nisi ut aliquid ex ea commodi consequatur"
4732947273,"laboriosam, nisi ut aliquid ex ea commodi consequatur"
8732947270,"ntium doloremque laudantium, totam rem aperiam, eaque ipsa "

【问题讨论】:

  • 你有文件吗?
  • @Andrey 我无法共享我正在使用的数据,但要重现只是创建一个包含 2 列的 CSV,第一列是序列号,第二列是简短描述(我使用了 lorem ipsum)。我用随机的 10 位数字和 lorem ipsum 创建了一个简短的 7 行 csv 文件,它仍然得到相同的结果。
  • 您是否有文件丢失标题或所有文件的问题?
  • @Andrey 只是缺少标题的文件。我为我制作的测试 csv 文件创建了一个临时下载链接。 expirebox.com/download/eb9bf54d625a5ac6c2832972359b107a.html
  • @Andrey 我复制了该测试文件并添加了标题,但它仍然返回未定义。我还从工作文件中复制了标题和前 7 行并将它们粘贴进去,但它也不起作用。

标签: perl csv parsing


【解决方案1】:

您的构造函数指定quote_char => "'",而您的示例数据文件使用双引号"

如果您在 CSV 数据中没有标题,那么您应该使用 names => 0 让模块返回数据数组,而不是按列名作为键的哈希

我还建议您明确地open 文件并检查它是否成功。然后您可以在file 参数中传递您所知道的有效文件句柄,而不是路径字符串

【讨论】:

  • 错误 else 块中的 Dumper 行现在输出第一行,但它仍然没有进入 while 循环。
【解决方案2】:

以下代码解析您发布的 test.csv 文件:

use strict;
use warnings;
use Text::CSV_XS;
my $csv = Text::CSV_XS->new ({ binary => 1, auto_diag => 1, sep_char => ',', allow_whitespace => 1, allow_loose_quotes => 1});
open my $fh, "<", 'test.csv' or die "Unable to open test.csv: $!";
while (my $row = $csv->getline ($fh)) {
    foreach my $filed (@$row) {
        print "[$filed]";
    }
    print "\n";
}
close $fh;

【讨论】:

    猜你喜欢
    • 2011-01-06
    • 2018-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多