結果

結果

次のようなファイルがあります:

paper 3
paper 6
eraser 2
pencil 9
pencil 44
pencil 1

次のように、共通の最初のフィールドを持つ行を合計したいと思います。

paper 9
eraser 2
pencil 54

標準の Unix ユーティリティを使用してこれを行うための便利なワンライナーはありますか? または、それほど標準的ではない Unix ユーティリティでもかまいません。

答え1

これを見てください:

$ echo "$a"
paper 3
paper 6
eraser 2
pencil 9
pencil 44
pencil 1

$ awk '{a[$1]=a[$1]+$2}END{for (i in a) print i,a[i]}' <(echo "$a")
pencil 54
eraser 2
paper 9

<(echo "$a)を次のように置き換えますfile:

$ awk '{a[$1]=a[$1]+$2}END{for (i in a) print i,a[i]}' file

答え2

あまり標準的ではないユーティリティでGNU データマッシュ

$ datamash --whitespace groupby 1 sum 2 < file
paper   9
eraser  2
pencil  54

あるいはもっと簡潔に

$ datamash -Wg 1 sum 2 < file
paper   9
eraser  2
pencil  54

答え3

印刷の順序を気にする場合は、次のようにします。

perl -lane '$h{$F[0]}+=$F[1]; $h[-1+keys%h]=$F[0]; END{print "$_ $h{$_}" for @h}'

ハッシュ内の特定の項目の実行中の合計%hと、配列内での特定の項目の出現順序を維持するという考え方です@h。ファイルの最後では、配列から順序を取得してハッシュ (キー + 値) を印刷するだけです@h

結果

paper 9
eraser 2
pencil 54

答え4

以下は、awk で書かれた、あまり可愛くないワンライナーです。

awk '{ if (prev && prev != $1) { print prev, sum; sum = 0 }; sum += $2; prev = $1 } END { print prev, sum }' < file.txt

最初のフィールドで同じ値を持つ行をグループ化する必要があります。 そうでない場合は、 できますsort file.txt | awk ...

関連情報