2014-03-19 26 views
-2

我有一個輸入文件,後面有5列,我想分別平均列數3,4,5 5,直到它的第二列值是5同樣地,對於第二列的值7和2使用perl連續排列的三列的平均值

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

是訂單(PHE,TRP,然後TYR),因爲那是有序還是因爲這是他們在輸入文件中出現的順序? – ysth

+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 
+0

如果任何問題持續存在,我會盡快通知。 –

+0

非常感謝你們..!它真的很難做到這一點 –

+0

是的親愛的............ –

0

尼斯解決方案mpapec。

我作爲一個實驗開始了以下解決方案,看看我是否可以編寫只需要一個for循環的東西,而不需要END塊。它分解爲6個循環,而且是一個完美的例子,除非您的目標是混淆,否則永遠不會編碼。

是的,它使用一個外部模塊。是的,這是我會發布的愚蠢代碼(我希望)。但至少它可能會讓某個人輕笑一下。而且,它是有效的! :)

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 
+0

首先,我認爲我的是不可讀的。 :)當你改變並且依賴於它之外的變量時,'map'也許不是個好選擇。 –

+0

讓我感到惱火的是,當進行逐行處理時,有時需要在發現組中發生更改時在for循環中複製處理調用,而且還需要在for循環之外複製處理調用,以捕獲eof之後剩下的任何內容。因此,我選擇了四處遊覽,看看我是否可以想出其他可行的構想。很明顯,我把這一個有點過分,但考慮到OP沒有表現出任何努力,它使我有興趣創建這個實驗:) – Miller

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 
+0

我使用哈希這個...如果你喜歡使用數組意味着嘗試二維嵌套循環的數組(想象爲矩陣...) – Muthu