如何在csv perl中转义逗号

时间:2015-07-22 09:34:25

标签: perl csv

在我的csv文件中有成千上万的记录。这些记录包含逗号数据。如何我应该逃脱。我看到很少提到有关使用模块的链接 TEXT :: CSV.But仍然存在问题,即recofds在逗号到来的地方得到破解。 以下是我一直在使用的示例代码:

 use Data::Dumper qw(Dumper);
 my $file = $ARGV[0] or die "Need to get CSV file on the command line\n";
 use Text::CSV;
 my $csv = Text::CSV->new({ sep_char => ',' });
 my $file = 'Pkg_Notes_small.csv';
 my %data;
  my %dupes;
  open(my $data, '<', $file) or die "Could not open '$file' $!\n";

 while (my $line = <$data>) 
 {

  my $catalog_num ='';
  my $catalog_sid ='';
  my $note_text ='';
  my $packing_notes_id ='';
  #($catalog_num,$catalog_sid,$packing_notes_id,$note_text) = split ',', $line;
  if ($csv->parse($line)) 
  {
      my @fields = $csv->fields();
      $catalog_num = $fields[0];
      $catalog_sid = $fields[1];
      $packing_notes_id = $fields[2];
      $note_text = $fields[3];
     }
   }

我将从csv文件添加样本数据:

CATALOG_NUM  CATALOG_SID    PACKAGING_NOTES_SID    PACKAGING_NOTES_DESC


112194  ,     521     ,        77      ,        For WI Packaging Operations: For 
                               finishing  operations, the  use of a protective 
为清楚起见,上面使用了逗号。现在根据我的要求将此数据转换为查询:

我得到的 Notetext 字段是:

    For WI Packaging Operations: For finishing operations  
错过了处理后,

此行的剩余部分。我期待的数据是:

  For WI Packaging Operations: For 
  finishing  operations, the  use of a protective

1 个答案:

答案 0 :(得分:5)

如果引用包含它们的字段,则可以在CSV文件中的记录中使用逗号。

field1,field2,"field3, with embedded comma",field4

但是Text :: CSV知道所有这些,所以如果你使用Text :: CSV并且仍然得到截断的记录,那么问题可能就在于输入数据。如果没有引用嵌入的逗号,那么解析器显然无法区分分隔符逗号和作为文本一部分的逗号。

field1,field2,field3, with embedded comma,field4

在上面的例子中,计算机怎么可能知道应该忽略第三个逗号?

如果这是您的问题并且您无法修复输入数据,那么有一种可能的解决方法。如果额外的逗号只存在于记录的最后一个字段中,那么您可以使用鲜为人知的第三个参数split()来限制从记录创建的字段数。

所以,如果你的记录是这样的:

field1,field2,field3,field4 with, embedded, commas

您可以使用:

my @data = split /,/ $input, 4;

强制split()仅将数据拆分为四个字段。第三个逗号之后的任何内容都被放入第四个字段。

通常使用split()解析CSV数据是一个非常糟糕的主意(因为它不知道忽略引用的逗号),但在这样的受控环境中,它可以很好地工作。

更新:现在我看到了输入数据的一些(好吧,一行!),我看到我的预测是正确的。您的数据中有未加引号的逗号。所以使用Text :: CSV不起作用。

但我的split()解决方案运行正常。这是一个例子:

#!/usr/bin/perl

use strict;
use warnings;
use 5.010;

while (<DATA>) {
  my @fields = split /,/, $_, 4;
  say $fields[3];
}

__END__
112194 , 521 , 77 , For WI Packaging Operations: For finishing operations, the use of a protective

我得到的输出是:

For WI Packaging Operations: For finishing operations, the use of a protective