我有一个输入文件,格式如下
ant,1
bat,1
bat,2
cat,4
cat,1
cat,2
dog,4
我需要为每个键(column1)聚合col2,结果是:
ant,1
bat,3
cat,7
dog,4
其他考虑因素:
谢谢!
这就是我想出来的......想看看这是否可以写得更好/更优雅。
open infile, outFile
prev_line = <infile>;
print_line = $prev_line;
while(<>){
curr_line = $_;
@prev_cols=split(',', $prev_line);
@curr_cols=split(',', $curr_line);
if ( $prev_cols[0] eq $curr_cols[0] ){
$prev_cols[1] += curr_cols[1];
$print_line = "$prev_cols[0],$prev_cols[1]\n";
$print_flag = 0;
}
else{
$print outFile "$print_line";
$print_flag = 1;
$print_line = $curr_line;
}
$prev_line = $curr_line;
}
if($print_flag = 1){
print outFile "$curr_line";
}
else{
print outFile "$print_line";
}
答案 0 :(得分:2)
#!/usr/bin/perl
use warnings;
use strict;
use integer;
my %a;
while (<>) {
my ($animal, $n) = /^\s*(\S+)\s*,\s*(\S+)/;
$a{$animal} += $n if defined $n;
}
print "$_,${a{$_}}\n" for sort keys %a;
这个简短的代码使您有机会学习Perl优秀的哈希工具,%a
。哈希是Perl的核心。没有它们,真的不能写出流利的Perl。
顺便提一下,该代码练习了Perl有趣的 autovivification 功能。第一次在输入流中遇到特定动物时,不存在计数,因此Perl隐含地假设预先存在的计数为零。因此,+=
运算符不会失败,即使它似乎应该失败。它只是在第一个实例中加零。
另一方面,可能不仅数据的数量而且动物的数量如此之大,以至于人们不想存储散列%a
。在这种情况下,人们仍然可以计算总数,只要数据按输入中的动物排序,就像在您的示例中一样。在这种情况下,类似下面的东西可能适合(虽然遗憾的是它不像上面那么整洁)。
#!/usr/bin/perl
use warnings;
use strict;
use integer;
my $last_animal = undef;
my $total_for_the_last_animal = 0;
sub start_new_animal ($$) {
my $next_animal = shift;
my $n = shift;
print "$last_animal,$total_for_the_last_animal\n"
if defined $last_animal;
$last_animal = $next_animal;
$total_for_the_last_animal = $n;
}
while (<>) {
my ($animal, $n) = /^\s*(\S+)\s*,\s*(\S+)/;
if (
defined($n) && defined($animal) && defined($last_animal)
&& $animal eq $last_animal
) { $total_for_the_last_animal += $n; }
else { start_new_animal $animal, $n; }
}
start_new_animal undef, 0;
答案 1 :(得分:1)
使用Perl的awk mode。
与
- 的 -a 强>
-n
或-p
一起使用时,会启用自动分割模式。对
split
数组的隐式@F
命令是while
或-n
生成的隐式-p
循环中的第一个内容。perl -ane 'print pop(@F), "\n";'
相当于
while (<>) { @F = split(' '); print pop(@F), "\n"; }
可以使用
-F
指定备用分隔符。
剩下的就是在哈希中累积总和并打印出来。
$ perl -F, -lane '$s{$F[0]} += $F[1];
END { print "$_,$s{$_}" for sort keys %s }' input
输出:
ant,1 bat,3 cat,7 dog,4
答案 2 :(得分:0)
在perl中它是微不足道的。循环文件输入。在逗号上拆分输入行。对于第一列中的每个键,保留一个哈希值,在第二列中添加值。在文件末尾打印哈希键及其值的列表。它可以在一行中完成,但这会混淆算法。