複数の行と列を持つファイルを取得し、一致するヘッダーを持つ列の値を水平方向に追加(合計)したいと思います。私のファイル(この例ではありません)は、最初の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
それが明確であることを願っています。