在我的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)
如果引用包含它们的字段,则可以在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)