ヘッダーを一致させて列を1つのファイルにマージする

ヘッダーを一致させて列を1つのファイルにマージする

複数の行と列を持つファイルを取得し、一致するヘッダーを持つ列の値を水平方向に追加(合計)したいと思います。私のファイル(この例ではありません)は、最初の9列と最初の行を無視します。結果に影響を与えずに印刷したいからです。

列は繰り返される順序ではなく、例よりも多くの列があります。

アイデアは次のとおりです。

入力する:

var x y x y x y
a 1 0 1 1 0 1
b 1 1 0 0 1 1
c 1 1 0 0 0 0

出力:

var x y
a 2 2
b 2 2
c 1 1

私がこれまでに得たものは次のとおりです...

awk -F '\t' '{FS==OFS} FNR==1; FNR>1 {for (i=10; i<=NF; i++) {} print}' FILE.tsv > FILE_norepcols.tsv

また、可能であれば、このコードをよりよく書く方法を理解しようとしています。

ベストアンサー1

$ perl -lane '$,="\t";
   print(qw/var x y/),next if $. == 1;
   push @A, shift @F;
   $A[$|--+1] += $_ for @F;
   print splice @A;
' file

結果:

var x   y
a   2   2
b   2   2
c   1   1

仮定:

  • フィールド数が奇数です。
  • フィールド#2とそれ以降のフィールドは両方とも数値です。

説明する(単に):

  • OPに示すように、タイトルは明示的に印刷されます。

  • @Aこの関数を使用して配列を印刷するときは、配列を消去して各行の配列を補充しますsplice

  • 配列はゼロインデックス付き@F入力レコードのフィールドを格納します。$_

  • 配列の最初の要素(0番目の要素ではない)が@A配列の前面から移動します@F。から新しいレコードを読み取るたびに@F配列が作成されますperl。これは$1, $2, $3, ..., $NFのフィールドに似ていますawk

  • 配列の残りの部分は、配列の対応する合計を累積する@Aバイナリ要素インデックスです。(0|1)+1=>(1|2)@F

それが明確であることを願っています。

おすすめ記事