次の形式の大きなファイルがあります。
2 1019 0 12
2 1019 3 0
2 1021 0 2
2 1021 2 0
2 1022 4 5
2 1030 0 1
2 1030 5 0
2 1031 4 4
列2の値が一致する場合、両方の行の列および4の値を合計します。それ以外の場合は、一意の行の値。
したがって、私が期待している出力は次のようになります。
2 1019 15
2 1021 4
2 1022 9
2 1030 6
2 1031 8
列2に従ってファイルをawk
またはsort
でソートし、最後の列をawk
で合計することができますが、個々の行に対してのみではありません列2が一致する2行。
私はこれをPerlで行います:
$ Perl -lane '$k{"$F[0] $F[1]"}+=$F[2]+$F[3];
END{print "$_ $k{$_}" for keys(%k) }' file
2 1019 15
2 1021 4
2 1030 6
2 1031 8
2 1022 9
またはawk:
awk '{a[$1" "$2]+=$3+$4}END{for (i in a){print i,a[i]}}' file
2番目の列に従って出力をソートする場合は、sort
にパイプするだけです。
awk '{a[$1" "$2]+=$3+$4}END{for (i in a){print i,a[i]}}' file | sort -k2
どちらのソリューションにも第1列が含まれていることに注意してください。アイデアは、ハッシュ(Perl)または連想配列(awk)へのキーとして、最初と2番目の列を使用することです。各ソリューションのキーはcolumn1 column2
したがって、2つの行が同じ列2で異なる列1を持つ場合、それらは別々にグループ化されます。
$ cat file
2 1019 2 3
2 1019 4 1
3 1019 2 2
$ awk '{a[$1" "$2]+=$3+$4}END{for (i in a){print i,a[i]}}' file
3 1019 4
2 1019 10
これは役立つかもしれませんが、列1は常に2であり、結果はそれに依存しますか?
awk '{ map[$2] += $3 + $4; } END { for (i in map) { print "2", i, map[i] | "sort -t't'" } }' file
または、ソートに関するコメントで glenn jackman によって言及されています:
gawk '{ map[$2] += $3 + $4; } END { PROCINFO["sorted_in"] = "@ind_str_asc"; for (i in map) { print 2, i, map[i] } }' file
データを事前にソートして、awkに詳細を処理させることができます。
sort -n infile | awk 'NR>1 && p!=$2 {print p,s} {s+=$3+$4} {p=$2}'
アキュムレータをリセットしたいかもしれません:
sort -n infile | awk 'NR>1 && p!=$2 {print p,s;s=0} {s+=$3+$4} {p=$2}'
出力:
1019 15
1021 19
1022 28
1030 34
最初の列を保持したい場合は、次のようにします。
sort -n infile | awk 'NR>1 && p!=$1FS$2 {print p,s} {s+=$3+$4} {p=$1FS$2}'
出力:
2 1019 15
2 1021 19
2 1022 28
2 1030 34
p
変数は、前の行の$2
値、または2番目のケースでは$1FS$2
を保持します。これは、前の行の{print p,s}
が現在の行の$2
と同じでない場合にp!=$2
がトリガーされることを意味します。
スイスアーミーナイフユーティリティの使用 mlr
:
mlr --nidx put '$5=$3+$4' then stats1 -g 1,2 -f 5 -a sum infile
出力:
2 1019 15
2 1021 4
2 1022 9
2 1030 6
2 1031 8
ノート:
--nidx
は、数値フィールド名を使用するようにmlr
に指示します。
put '$5=$3+$4'
は、新しい5番目のフィールドを作成し、フィールドの合計3および4。
stats1
関数(または "verb")は、小さなスイスアーミーナイフですmlr
、sum
、count
、mean
、など
stats1 -g 1,2
は、データを列1および2でグループ化し、-f 5 -a sum
次に、これらのグループのフィールド5を合計します。 stats1
名前付きフィールドのみを出力します。