2013-12-23 53 views
1

我有個製表符分隔的文件如計算兩個相鄰行之間的百分比差異唯一

Name S.No Points First 
Jack 2 98 F 
Jones 6 25 
Mike 8 11 
Jasmine 5 7 
Gareth 1 85 F 
Simon 4 76 
Mark 11 12 
Steve 17 8 
Clarke 3 7 

我想要計算前3點仔和由線F和另外兩個表示的第一點仔之間差該組的平均總分數。例如,Jones和Mike在第一個案例中,Simon和Mark在第二個案例中。我希望我的輸出是

Name S.No Points First 
Jack 2 98 F 
Jones 6 25 51.77 
Mike 8 11 61.70 
Gareth 1 85 F 
Simon 4 76 4.78 
Mark 11 12 44.68 

計算比例的公式是在輸出的最後一列是,例如,在瓊斯的情況下,在個案1是

(Jack - Jones)*100/(Jack + Jones + Mike + Jasmine) 
(98-25)*100/(98+25+11+7)= 51.77 

我可以選擇第一使用

awk '$NF~/E/{c=3;next}c-->0' 

然而,計算差和比例有點麻煩,因爲我有消除前三名行之前總結分母三大行。

+2

所以每個F開始一個新組(和標誌着一個比較別人),並希望在F紀錄,另外兩個爲每個組?它總是以下兩條記錄? – ysth

+0

是的,F開始一個新的組,並且我想要以下兩個記錄 – discipulus

回答

1

獲得一個完全不同的編號爲商標:

use 5.010; 
use strict; 
use warnings; 
use autodie; 
use List::Util 'sum'; 

open my $infile, '<', 'foo.txt'; 
my @groups; 
my $group; 
while (my $line = <$infile>) { 
    chomp $line; 
    my ($name, $sno, $points, $first) = split /\t/, $line; 
    if ($first && $first eq 'F') { 
     $group = []; 
     push @groups, $group; 
    } 
    push @$group, { 'name' => $name, 'sno' => $sno, 'points' => $points, 'first' => $first }; 
} 

say join "\t", qw/Name S.No Points First/; 
for my $group (@groups) { 
    my $total_points = sum map $_->{'points'}, @$group; 
    my $first_points = $group->[0]{'points'}; 

    say join "\t", @{ $group->[0] }{ qw/name sno points first/ }; 

    for my $other (1..2) { 
     if ($group->[$other]) { 
      say join "\t", @{ $group->[$other] }{ qw/name sno points/ }, sprintf "%.2f", 100 * ($first_points - $group->[$other]{'points'})/$total_points; 
     } 
    } 
} 

生產:

Name S.No Points First 
Jack 2 98 F 
Jones 6 25 51.77 
Mike 8 11 61.70 
Gareth 1 85 F 
Simon 4 76 4.79 
Mark 11 12 38.83 
1

下面是一個AWK溶液:

awk -f c.awk input.txt input.txt 

c.awk哪裏是:

NR==FNR { 
    if ($NF=="F") { 
     key1=$1 
     A[key1]=$3 
     B[key1]=$3 
    } 
    else if (key1) 
     B[key1]+=$3 
    next 
} 
key && NF==3 { 
    if (++k<3) { 
     $4=((A[key]-$3)*100)/B[key] 
     print 
    } 
    next 
} 

$NF=="F" { 
    key=$1 
    k=0 
} 

{print} 
+0

這個文件的兩個傳遞是一個好主意 – ysth

2

引用你的awk命令,似乎源文件已經按組對數據進行了排序。

awk 'NR==FNR{if ($NF=="F") {s=$1}; a[s]+=$3;next} 
    { if (FNR=="1") {print;next} 
     if ($NF=="F") {s=$1;b=$3;c=3;print;next} 
     if (--c>0){ printf "%s %.2f\n", $0,(b-$3)*100/a[s];} 
    }' file file 

結果

Name S.No Points First 
Jack 2 98 F 
Jones 6 25 51.77 
Mike 8 11 61.70 
Gareth 1 85 F 
Simon 4 76 4.79 
Mark 11 12 38.83