我有一个名为listofvalues.txt
的文件。该文件有超过1000行和5列。
1,232,3434,54343,434343
1,232,100,4546,3456
1,122,45454,4546,3456
2,212,334,5555,4654
...
...
如果第1列和第2列相等,我想将第三列的值相加,并将结果打印到如下文件中
1,232,3534,54343,434343
1,122,45454,4546,3456
2,212,334,5555,4654
....
.........
.........
......
你认为我怎么能在Perl中做到这一点?由于我是Perl的新手,我发现很难做到。
答案 0 :(得分:3)
此程序的工作原理是维护一个数组@data
,其中包含具有唯一column1|column2
个键的所有记录的列表。第一次在文件中遇到新密钥时,完整记录被压入堆栈。每次后续遇到只会将记录的第三个字段添加到原始值。
哈希%data
维护对与密钥的每个不同值对应的@data
元素的引用。
use strict;
use warnings;
open my $fh, '<', 'listofvalues.txt' or die $!;
my @data;
my %data;
while (<$fh>) {
chomp;
my @record = split /,/;
my $key = join '|', @record[0,1];
if ($data{$key}) {
$data{$key}[2] += $record[2];
}
else {
push @data, ($data{$key} = \@record);
}
}
print join(',', @$_), "\n" for @data;
<强>输出强>
1,232,3534,54343,434343
1,122,45454,4546,3456
2,212,334,5555,4654
<强>更新强>
单线解决方案
perl -F, -ane '$k="@F[0,1]";$s{$k}?$s{$k}[2]+=$F[2]:do{push@d,$k;$s{$k}=[@F]};END{$\"=',';print"@{$s{$_}}"for@d}' listofvalues.txt
答案 1 :(得分:1)
这是另一个单行的:
perl -F, -lane '
BEGIN { $, = "," }
if(defined(@A)) {
if($A[0] == $F[0] and $A[1] == $F[1]) {
$A[3] += $F[3];
} else {
print @A;
@A = (@F);
}
} else {
@A = (@F);
}
END { print @A }' listofvalues.txt
请参阅perlrun(1)
了解交换机的含义。
答案 2 :(得分:0)
仅仅因为你可以在一行中做到并不意味着你应该;)
$ perl -F',' -lane '
push @order, [ @F[0,1] ]
unless $seen{$F[0]}{$F[1]}++; # Preserve order
$total{$F[0]}{$F[1]} += $F[2]; # Sum up
$value{$F[0]}{$F[1]} = join ',' => @F[0,1], $total{$F[0]}{$F[1]}, @F[3..$#F];
} END {
print $value{$_->{0]}{$_->[1]} for @order;
' file.txt
答案 3 :(得分:0)
您可以尝试数据库方法,但它不处理col4或col5。
#!/usr/bin/perl
use strict;
use warnings;
use DBI;
my $dbh = DBI->connect("DBI:CSV:");
$dbh->{'csv_tables'}->{'data'} = { 'file' => 'o33.txt',
'col_names' => [qw/col1 col2 col3 col4 col5/]};
my $sql = <<SQL;
select col1, col2, SUM(col3)
from data
group by col1, col2
order by col1, col2
SQL
my $sth = $dbh->prepare( $sql );
$sth->execute;
{
local $" = ',';
while ( my $row = $sth->fetchrow_arrayref ) {
print "@$row\n";
}
}
__END__
C:\Old_Data\perlp>type o33.txt
1,232,3434,54343,434343
1,232,100,4546,3456
1,122,45454,4546,3456
2,212,334,5555,4654
C:\Old_Data\perlp>perl t3.pl
1,122,45454
1,232,3534
2,212,334