我有一个包含以下5列的输入文件,我希望将列号3,4,5分别平均为3,4,5,直到其第二列值为5,类似于第二列值7和2。
PHE 5 2 4 6
PHE 5 4 6 4
PHE 5 4 2 8
TRP 7 5 5 9
TRP 7 5 7 1
TRP 7 5 7 3
TYR 2 4 4 4
TYR 2 4 4 0
TYR 2 4 5 3
我想要一个像这样的输出
PHE 5 3.3 4 6
TRP 7 5 6.3 4.3
TYR 2 4 4.3 2.3
答案 0 :(得分:0)
perl -lane'
$k = join "\t", splice(@F, 0, 2);
$h{$k}{c}++ or push(@r, $k);
$h{$k}{t}[$_] += $F[$_] for 0 .. $#F;
END {
$, ="\t";
for (@r) {
($t, $c) = @{$h{$_}}{"t", "c"};
print $_, map sprintf("%.1f", $_/$c)*1, @$t;
}
}
' file
输出
PHE 5 3.3 4 6
TRP 7 5 6.3 4.3
TYR 2 4 4.3 2.3
答案 1 :(得分:0)
很好的解决方案mpapec。
我开始使用以下解决方案作为实验,看看我是否可以编写只需要一个for循环的东西,而不需要END块。它代之以6代for循环,是一个完美的例子,说明除非你的目标是混淆,否则永远不会编码。
是的,它使用外部模块。是的,它是我发布过的愚蠢的代码(我希望)。但至少它可能会让某人轻笑。是的,它的确有效! :)
use Array::Transpose;
use List::Util qw(sum max);
use strict;
use warnings;
my $g;
my $l;
print "$_\n" for map {
join ' ', map {sprintf "%-$_->[0]s", $_->[1]} transpose [$l, $_]
} grep {
$l = [map {max @$_} transpose [[map {length $_} @$_], $l || ()]]
} [qw(Txt Num Ave Ave Ave)], map {
my @c = transpose $_;
[$c[0][0], $c[1][0], map {map {/\./ ? sprintf("%.1f", $_) : $_} sum(@$_) / @$_} @c[2..$#c]]
} map {
$g && $g->[0][0] eq $_->[0] ? (push @$g, $_) && () : ($g = [$_])
} map {[split]} (<DATA>);
__DATA__
PHE 5 2 4 6
PHE 5 4 6 4
PHE 5 4 2 8
TRP 7 5 5 9
TRP 7 5 7 1
TRP 7 5 7 3
TYR 2 4 4 4
TYR 2 4 4 0
TYR 2 4 5 3
输出
Txt Num Ave Ave Ave
PHE 5 3.3 4 6
TRP 7 5 6.3 4.3
TYR 2 4 4.3 2.3
答案 2 :(得分:0)
不使用模块的脚本。
试试这个......
#!/usr/bin/env perl
open(DATA, "<input.txt") or die "Couldn't open file file.txt, $!";
my %h=();
my %c=();
print "\n";
while(<DATA>){
my $temp=$_;
if($temp=~m/^([A-Z]{3})\s+([\d]+)\s+([\d]+)\s+([\d]+)\s+([\d]+)/is)
{
my $key=$1;
$h{$key}{1} +=$2;
$h{$key}{2} +=$3;
$h{$key}{3} +=$4;
$h{$key}{4} +=$5;
if($c{$key})
{
$c{$key}++;
}
else
{
$c{$key}=1;
}
}
}
foreach $key (sort(keys %h)) {
#print $key.'='.$h{$key}{1}/$c{$key}." ".$h{$key}{2}/$c{$key}." ".$h{$key}{3}/$c{$key}." ".$h{$key}{4}/$c{$key};
printf("%s %d %.1f %.1f %.1f", $key, $h{$key}{1}/$c{$key},$h{$key}{2}/$c{$key},$h{$key}{3}/$c{$key},$h{$key}{4}/$c{$key});
print "\n";
}
print "\n";
close(DATA);
______OUTPUT________
PHE 5 3.3 4.0 6.0
TRP 7 5.0 6.3 4.3
TYR 2 4.0 4.3 2.3