3列ごとにすべての行の平均を取得します。

3列ごとにすべての行の平均を取得します。

Ubuntu 14.04を使用しています。タブ区切りファイルがある場合:

例フィールドフィールド2フィールド3フィールド4フィールド5フィールド6フィールド7フィールド8フィールド9フィールド10フィールド11フィールド12

サンプル 1 1 2 3 4 5 6 7 8 9 10 11 12

すべての行(それぞれ3列)の列平均を印刷したいと思います。出力は次のとおりです。

例 fieldsField2 Field3 Field4

サンプル 2 5 8 11

よろしくお願いします!

答え1

私はこれを次のように解決します:

#!/usr/bin/perl

use warnings;
use strict;

my $field_count = 3;

#discard first row, as the fields don't match
my $first_row = <>;
#iterate STDIN or files specified on command line, just like grep or sed do. 
while ( <> ) {
   #extract the name and values. Maybe you need a 'chomp' to remove linefeeds 
   #it works given your sample data, because the last field is a number. 
   my ( $samplename, @fields ) = split; 
   my @new_fields; 
   while ( @fields ) {
      #extract fields 3 at a time.  
      my @group = splice @fields, 0, $field_count;
      #sum them
      my $sum = 0;
      $sum += $_ for @group;

      my $avg = $sum / @group; #divide by number of elements in this group, so it'll work if there's 1 or 2 'trailing'. 
      #stash that in the new field list. 
      push @new_fields, $avg;
   }
   #print the output line. 
   print join "\t", $samplename, @new_fields,"\n"
}

答え2

A1 Perl:すべてのラインでレガシーを使用する

入力形式仮定:SampleId、3つの値グループ

perl -nE '($out,@g)=split;                   #sampleId a1 b1 c1  a2 b2 c2 ...
          while(($a,$b,$c,@g)=@g){           
             $out .= " ".($a+$b+$c)/3 }
          say $out '

または

A2 Perl:正規表現を使用した置換と評価

perl -pe 's!\b(\d+)\s+(\d+)\s+(\d+)! ($1+$2+$3)/3 !ge'

関連情報