Shell-Script

如何分別根據其他列中的變數獲取列中值的總和?

  • November 27, 2018

我有一個如下表數據

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

我認為我的程式碼的結尾是錯誤的,但不知道如何修復它。我需要一些指導來修復程式碼。

你很接近。你明白你做錯了什麼,不是嗎?您為每個第 1 列值保留一個總計,而您應該保留三個。

這類似於Inian 的答案,但可以輕鬆擴展以處理任意數量的列:

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 的回答那樣保留三個數組,而是保留一個二維數組。

只要您的文件是製表符分隔的,datamash就非常適合。

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

如果您指定 .Datamash 也可以使用非選項卡-t <delimiter>。但選項卡似乎最接近您提供的範例輸入。

如果您的輸入由任意空格分隔(即可能的多個空格旨在“看起來像”一個選項卡),則Datamash*將不起作用。*儘管如此,即使這就是您的數據的樣子,它也很容易變成 datamash 所期望的形式:

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

引用自:https://unix.stackexchange.com/questions/484370