【问题标题】:Perl Text::CSV $csv->fields() property not populatedPerl Text::CSV $csv->fields() 属性未填充
【发布时间】:2015-12-30 04:21:38
【问题描述】:

我有一个脚本,它可以将来自 CSV 的传入数据重新格式化为销售系统的可读格式。我可能会发疯,但我很确定它在一两个星期前在生产环境中工作。但是,在过去一两周的某个时间点,它停止了工作。我将问题追溯到 Text::CSV 模块没有填充 $csv->fields() 属性。

my $csv = Text::CSV->new({sep_char => '|', allow_loose_quotes => 1});
$csv->column_names($csv->getline(*READ));
my @keys = $csv->fields;

现在,在我的本地机器上(至少在我的脑海中,两周前的生产环境中也是如此),这将使用已解析的标头字段填充 @keys。但是,现在,在生产和预生产中,这都失败了。我能看出的唯一区别是我的机器运行的是 perl 5.12.4,而 prod/pprd 是 5.8.8。两者的 Text::CSV 模块都是 1.21。

在我的机器上,如果我使用 Data::Dumper 并转储 $csv 对象,部分属性是

'_FIELDS' => [
    'ID',
    'IDCARD_TYPE',
    'FIRST_NAME',
    'MIDDLE_NAME',
    'LAST_NAME',
    ...
    'EMAIL',
],

在其他机器上:

'_FIELDS' => undef,

我已经通过使用 $csv->column_names 来填充 @keys 来解决这个问题,但似乎有些不对劲,我真的很想弄清楚发生了什么。有什么想法吗?

【问题讨论】:

  • 当你转储$csv->getline(*READ) 结果时会发生什么?
  • 它返回一个数组,其字段名称类似于_FIELDS 属性中的名称,并显示在_COLUMN_NAMES 属性中。这在我的机器和 prod/pprd 机器上是相同的。

标签: perl csv


【解决方案1】:

根据Text::CSV documentation,返回undeffields()调用getline()后的预期结果。首先尝试使用parse()。您可能在本地计算机上使用此模块的不同版本。您可以使用perl -MText::CSV -e 'print $Text::CSV::VERSION'查看版本。

注意,使用getline()后返回值是未定义的,即 不填充parse()返回的数据结构。

【讨论】:

  • 使用$csv->column_names安全吗?我已经重写了使用解析的代码,现在我可以使用$csv->fields,我只是想了解使用模块的正确方法。 $csv->column_names,根据文档,不应该返回任何东西,不是吗?
【解决方案2】:

以下替代顺序对我有用:

$file = "test.csv" ;      
if(!open($fh, "<", $file )) {
  # Cannot call getline is a symptom of a bad open() 
  printf("### Error %s: could not open file %s\n", $ws, $file) ;
  close($fh) ;
  exit 1 ;
}
while(my $row = $csv->getline($fh)) {
  # $row is a pointer to an Array
  #     The array is already parsed.
  @items = @{$row} ;
  for(my $i=0 ; $i<=$#items; $i++) {
    printf("Field %d: (%s)\n", $i, $items[$i] ) ;
  }
}
close $fh ;

【讨论】:

    猜你喜欢
    • 2021-09-12
    • 2019-07-23
    • 1970-01-01
    • 1970-01-01
    • 2019-09-29
    • 2015-02-06
    • 2017-01-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多