複数のファイルからデータを収集し、単一の要約ファイルにダンプしています。
cat *files* | sort -u > final.rpt
a 1
a 5
a 6
b 2
b 3
b 0
c 1
c 7
最初の列の文字列に基づいて一意化し、2番目の列の文字列に対応するすべての数値を合計するにはどうすればよいですか?上記の例で予想される出力は次のとおりです。
a 12
b 5
c 8
答え1
次の操作が実行されます。
awk '{a[$1]+=$2} END {for (i in a) print i, a[i]}' <input file>
アイデアは、連想配列を使用して2番目の列の値を合計することです。
答え2
使用datamash
:
$ datamash -sW sum 2 -g 1 <file
これにより、最初のフィールドsum
だけでなく2番目のフィールドも計算されます。groupby
使用Miller
:
$ mlr --nidx stats1 -a sum -f 2 -g 1 file
ソートされていないファイルには、次の2つのフィールドしかないとします。
a 1
a 5
a 6
b 2
b 3
b 0
c 1
c 7
a 1
次のコマンドは最初にファイルをソートしてから合計を計算します。
$ mlr --nidx uniq -f 1,2 then \
stats1 -a sum -f 2 -g 1 file
答え3
完全性のために、以下はO(1)メモリ使用ソリューションです。
awk 'NR>1 && $1!=prev {print prev, sum;sum=0} {sum+=$2;prev=$1} END {print prev, sum}' < final.rpt
a 12
b 5
c 8
説明:$ 1が変更された新しいレコードごとに結果を印刷し、合計をリセットします。また、ファイルの末尾に結果を印刷しますが、先頭には印刷しません(NR> 1)。このコードは、連想配列バージョンと比較して少し面倒です。
答え4
... | sort | uniq -c >final.rpt
(を使用する代わりに... | sort -u >final.rpt
)を使用してデータを収集できますか?