web-dev-qa-db-ja.com

他の列の変数に基づいて列の値の合計を個別に取得するにはどうすればよいですか?

以下のようなテーブルデータがあります

abc 1   1   1
bcd 2   2   4
bcd 12  23  3
cde 3   5   5
cde 3   4   5
cde 14  2   25

最初の列の変数に基づいて各列の値の合計が必要で、望ましい結果は以下のようになります。

abc 1   1   1
bcd 14  25  7
cde 20  11  35

私はこのようなawkコマンドを使用しました

awk -F"\t" '{for(n=2;n<=NF; ++n)a[$1]+=$n}END{for(i in a ) print i, a[i] }' tablefilepath

そして私は以下の結果を得ました:

abc 3
bcd 46
cde 66

コードの終わりが間違っていると思いますが、修正方法がわかりません。コードを修正するためのいくつかの指示が必要です。

4
awkprob

あなたはかなり近くにいた。あなたはあなたが間違っていたことを理解しますね? 3つ保持する必要があったのに、列1の値ごとに合計1つを保持していました。

これは イニアンの答え に似ていますが、任意の数の列を処理するために簡単に拡張できます。

awk -F"\t" '{for(n=2;n<=NF; ++n) a[$1][n]+=$n}
        END {for(i in a) {
                printf "%s", i
                for (n=2; n<=4; ++n) printf "\t%s", a[i][n]
                printf "\n"
             }
        }'

Inianの答えのように3つの配列を保持するのではなく、2次元配列を保持します。

4
Scott

ファイルがタブ区切りである限り、 datamash がこれに適しています。

$ datamash groupby 1 sum 2 sum 3 sum 4 < tablefilepath
abc     1       1       1
bcd     14      25      7
cde     20      11      35

-t <delimiter>を指定すると、Datamashは非タブでも機能します。ただし、タブは、指定した入力例に最も近いように見えます。

入力が任意の空白(つまり、タブのように見えることを目的とした複数のスペースの可能性)で区切られている場合、Datamashは機能しません。それでも、それがあなたのデータがどのように見えるものであっても、それはdatamashが期待する形式に簡単に変換されます。

sed -i 's/ \+/\t/g' tablefilepath
4
cryptarch

awkを使用して、1に基づいて列2〜4を合計します。

awk -v FS="\t" -v OFS="\t" '{ col1[$1]+=$2; col2[$1]+=$3; col3[$1]+=$4; next } END { for ( i in col1) print i, col1[i], col2[i], col3[i]  }' file
2
Inian