【发布时间】:2018-03-01 03:32:36
【问题描述】:
我有一个带有多行的 csv(由 , 分隔)。 csv 有 4 列,其中前 3 列包含多行文本,而 group by 发生在最后一列。
输入 csv 内容:/tmp/test.tmp.csv
"Total Sections",ota,4!n,01
"Input History",80,"HHMM28!c1!a[4!a]
6X
9X]",1
"T (MR)",17t,(MTR),02
"Input History",80,"HHMM28!c1!a[4!a]
6X
9X]",2
Reference,:4!t/1c,:(Text1)/(Text2),30
Reference,:4!t/1c,:(Text1)/(Text2),32
上面的csv由6条记录组成,记录2和4是多行的。
预期输出(按单独分组是空格):
"Total Sections",ota,4!n,01
"Input History",80,"HHMM28!c1!a[4!a]
6X
9X]",1 2
"T (MR)",17t,(MTR),02
Reference,:4!t/1c,:(Text1)/(Text2),30 32
我的 perl 脚本(读取 hash 中的前 3 个字段作为 key,hash 中的最后一个字段作为 value,通过 join 打印到 csv):
#!/usr/bin/perl -w
use strict;
use warnings;
use Text::CSV;
my %hash;
my @array;
my $in_qfn = "/tmp/test.tmp.csv";
my $out_qfn = "/tmp/test.out.tmp.csv";
# Li: Parsing multilines in csv
my $parser = Text::CSV->new({
binary => 1,
auto_diag => 1,
sep_char => ','
});
# Li: output multilines to csv
my $csvo = Text::CSV->new({
binary => 1,
eol => "\r\n",
sep_char => ','
});
open(my $data, '<:encoding(utf8)', $in_qfn) or die "Could not open $in_qfn: $!\n";
open(my $sts, '>:encoding(utf8)', $out_qfn) or die "Could not write $out_qfn: $!\n";
while (my $fields = $parser -> getline($data)) {
my $fz = $fields->[0];
my $fo = $fields->[1];
my $ft = $fields->[2];
my $fth = $fields->[3];
my @flds = ($fz, $fo, $ft, $fth);
# Li: push the first 3 columns as key and the last column as value
push(@{$hash{@flds[0..2]} }, $flds[3]);
}
# Li: print to output csv without join yet
for my $k (sort keys %hash) {
my @fldsAll = ($k, @{ $hash{$k}});
print("###LI### 1: key: $k, value: @fldsAll\n");
$csvo -> print($sts, \@fldsAll);
}
但是,脚本不能完美运行,哈希键由于多行和可能的特殊字符而丢失,并且到处都没有双引号。
输出缺陷:
(MTR),02
4!n,01
:(Text1)/(Text2),30,32
"HHMM28!c1!a[4!a]
6X
9X]",1,2
关于如何解决它的任何想法?或者一个全新的 perl 解决方案也很感激。
【问题讨论】:
-
您希望哈希键是一个数组吗?您当前只是使用数组的最后一个成员。
-
是的,我确实希望使用数组切片:@flds[0..2] 作为哈希键。不正确吗?我还尝试分配@fldsSlc=@flds[0..2],并将数组@fldsSlc 分配为哈希键,同样的问题。