一致するフィールドに基づいて列の合計

一致するフィールドに基づいて列の合計

次の形式の大容量ファイルがあります。

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列一致し、次の値を合計したいと思います。3列そして42行の値、それ以外の場合は一意の行の値の合計です。

だから私が望む出力は次のようになります。

2 1019 15 
2 1021 4 
2 1022 9 
2 1030 6 
2 1031 8

次の基準に従ってファイルを並べ替えることができます。2列awkORを使用しsortて最後の列の合計を取得しますawk。ただし、2行ではなく単一行にのみ適用されます。2列マッチ。

答え1

私は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 '{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

どちらのソリューションも最初の列を含みます。アイデアは、最初と2番目の列をハッシュ(perl)または関連配列(awk)のキーとして使用することです。各ソリューションの鍵は、2column1 column2行目の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

答え2

おそらくこれが役に立ちます。しかし、列1は常に2であり、結果はそれに応じて変わりますか?

awk '{ map[$2] += $3 + $4; } END { for (i in map) { print "2", i, map[i] | "sort -t't'" } }' file

または述べたようにグレンジャックマンソートの説明:

gawk '{ map[$2] += $3 + $4; } END { PROCINFO["sorted_in"] = "@ind_str_asc"; for (i in map) { print 2, i, map[i] } }' file

答え3

データを事前にソートし、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前の行の値($1FS$2上記の2番目の場合)を保持します。つまり、現在の行が現在の行と異なる場合()が実行されます{print p,s}$2p!=$2

答え4

Swiss Army Knifeユーティリティの使用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

メモ:

  • --nidxmlr数値フィールド名を使用するように指示します。

  • put '$5=$3+$4'新規5番目の場所フィールド、フィールドの合計サムそして4

  • 関数stats1(または「動詞
    ")は、より大きなSwiss Army Knivesのうちより小さいSwiss Army Knifeであり、、、、、、mlrなど様々なアキュムレータベースの機能を備えています。sumcountmeanなど。

    stats1 -g 1,2列別にデータをグループ化1そして2-f 5 -a sumをクリックして、そのグループのフィールドを追加します。5stats1 名前付きフィールドのみを印刷します。

関連情報