如何在csv perl中转义逗号

Ani*_*kar 1 csv perl

在我的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];
     }
   }
Run Code Online (Sandbox Code Playgroud)

我将从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 
Run Code Online (Sandbox Code Playgroud)

为清楚起见,上面使用了逗号.现在根据我的要求将此数据转换为查询:

为此Notetext场我得到的是:

    For WI Packaging Operations: For finishing operations  
Run Code Online (Sandbox Code Playgroud)

处理完毕后,该线路的剩余部分将被遗漏.我希望的数据是:

  For WI Packaging Operations: For 
  finishing  operations, the  use of a protective
Run Code Online (Sandbox Code Playgroud)

Dav*_*oss 6

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

field1,field2,"field3, with embedded comma",field4
Run Code Online (Sandbox Code Playgroud)

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

field1,field2,field3, with embedded comma,field4
Run Code Online (Sandbox Code Playgroud)

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

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

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

field1,field2,field3,field4 with, embedded, commas
Run Code Online (Sandbox Code Playgroud)

您可以使用:

my @data = split /,/ $input, 4;
Run Code Online (Sandbox Code Playgroud)

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

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

更新:现在我已经看到了输入数据的一些(好吧,一行!),我看到我的预测是正确的.您的数据中有未加引号的逗号.所以使用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
Run Code Online (Sandbox Code Playgroud)

我得到的输出是:

For WI Packaging Operations: For finishing operations, the use of a protective
Run Code Online (Sandbox Code Playgroud)

  • 啊.当我看着它时,它看起来不像是一个换行符.不,这会使事情大规模复杂化: - / (3认同)