我有一个csv文件,
id1,v1,v2,v3,v4
id2,v1,v2,v6,v4
id1,v7,v8,v3,v9
id1,v10,v11,v12,v13
id2,v3,v5,v8,v7
因为,文件没有排序,不应该! 我希望输出为:
id1,v1|v7|v10,v2|v8|v11,v3|v12,v4|v9|v13
id2,v1|v10,v2|v5,v6|v8,v4|v7
其中,列中的所有相应值都合并到具有相同id的记录中的相应列,但重复值除外(请参阅第3列中针对id1的v3)和id。
我使用此处http://www.robelle.com/tips/st-export-notes.html给出的代码尝试了它。但它需要的远不止于此。
如何使用perl实现这一目标?我是perl的新手。提前谢谢!
答案 0 :(得分:1)
假设您不需要任何特定的排序顺序,您可以使用数组哈希来解决此问题。哈希被称为其他语言的词典。
use strict;
use warnings;
my %data;
while ( <DATA> ) {
my ($id, @vals) = /[^,\s]+/g;
for my $i ( 0 .. $#vals ) {
++$data{$id}[$i]{$vals[$i]};
}
}
while ( my ($id, $vals) = each %data ) {
my @vals = map { join '|', keys %$_ } @$vals;
printf "%s,%s\n", $id, join ',', @vals;
}
__DATA__
id1,v1,v2,v3,v4
id2,v1,v2,v6,v4
id1,v7,v8,v3,v9
id1,v10,v11,v12,v13
id2,v3,v5,v8,v7
<强>输出强>
id2,v1|v3,v5|v2,v8|v6,v7|v4
id1,v7|v10|v1,v11|v2|v8,v12|v3,v4|v13|v9
答案 1 :(得分:-1)
您应该为CSV数据使用正确的CSV解析器
use strict;
use warnings;
use Text::CSV;
my $csv = Text::CSV->new( { binary => 1, eol => $/ } );
my %data;
while ( my $row = $csv->getline(*DATA) ) {
my $id = shift @$row;
$data{$id}[$_]{ $$row[$_] } = undef for 0 .. $#$row;
}
for my $id ( sort keys %data ) {
my $vals = $data{$id};
$csv->print( \*STDOUT, [ $id, map { join '|', sort keys %$_ } @$vals ] );
}
__DATA__
id1,v1,v2,v3,v4
id2,v1,v2,v6,v4
id1,v7,v8,v3,v9
id1,v10,v11,v12,v13
id2,v3,v5,v8,v7