次のファイルがあります。
Bitrate ASNUM TotalBytes DownloadTime NumberCount
280000 2856 61454 12
280000 2856 61428 14
1179968 2856 309430 11
1179968 4156 309200 15
4864960 2856 997962 193
4864960 2856 1115576 300
4864960 2856 997962 116
最初の2つの列(ビットレートやASNUMなど)に基づいて行をマージし、対応する合計バイトフィールドとダウンロード時間フィールドを追加する必要があります。
結果の出力は次のようになります。
Bitrate ASNUM TotalBytes DownloadTime NumberCount
280000 2856 122882 26 2
1179968 2856 309430 11 1
1179968 4156 309200 15 1
4864960 2856 3111500 609 3
追加の列 NumberCount は、発生回数を示します。
この機能を達成できるコードを実装するのに役立ちますか?
答え1
awkを使用するソリューションは次のとおりです。
awk -F " " '
NR==1 {print; next}
NF {a[$1" "$2]+=$3; b[$1" "$2]+=$4; c[$1" "$2]++}
END {for(i in a)print i, a[i], b[i], c[i]}
' file
--> inputFileは、コマンドが実行されるディレクトリになければなりません。
--> -F ""は単一のスペースを区切り文字と見なします。
--> NR==1{print;next} 出力するタイトルを印刷してスキップします。
--> 配列 a[$1" "$2] は、最初の列値と 2 番目の列値のグループ化基準を考慮します。配列bとcは同じです。
--> +=演算子は、配列のグループ化に従って必要な列を合計します。
--> 配列 c で使用される++演算子は、グループ数を格納します。
-->最後の「for」ループは出力結果を印刷するために使用されます。
答え2
GNUデータの混合これらの作業のために設計されています。
datamash -WH -g 1,2 sum 3,4 count 4
それとももっと詳しく
datamash --whitespace --headers \
groupby Bitrate,ASNUM sum TotalBytes,DownloadTime count DownloadTime
(どのグループ化されていないフィールドを指定するかは関係ありませんcount
。)
空白行は状況が少し複雑になります。ただし、以前に空白行を削除して後で再度追加するだけです。
sed '/^$/d' file | datamash -WH -g 1,2 sum 3,4 count 4 | column -t | sed G
GroupBy(Bitrate) GroupBy(ASNUM) sum(TotalBytes) sum(DownloadTime) count(DownloadTime)
280000 2856 122882 26 2
1179968 2856 309430 11 1
1179968 4156 309200 15 1
4864960 2856 3111500 609 3