同じデータIDを持つ列の値を追加しますか?

同じデータIDを持つ列の値を追加しますか?

日別、子日データが混在した状態で、子日値を追加し、均一な日別データを生成し、均一な日別データを準備したいと思います。私のサンプル入力と必須出力データは次のとおりです。

入力ファイル:

date            Value
01/01/2000     2
01/01/2000     2
01/02/2000     6
01/03/2000     5
01/03/2000     4

必須出力ファイル:

date          Value
01/01/2000    4 (i.e. 2+2)
01/02/2000    6
01/03/2000    9(i.e 5+4)

答え1

行が時系列でソートされている場合:

awk '
 NR==1{print;next}
 $1!=l && NR>2{print l,n;n=0}
 {n+=$2;l=$1}
 END{if (NR>1) print l,n}' < input.file > output.file

つまり、最初のフィールドが最後の行と異なることを確認すると、数を出力します。つまり、すべてのデータをメモリに保存し、表示が終了するまで待つ必要はありません。バレンスまたは持続可能な開発管理解決策。これはまた、注文が自動的に保留されることを意味します。

答え2

AWKに関連付けられた配列を使用してこれを実行できます。

awk '{ 
    if (NR == 1) { print $0 } 
    else { count[$1] += $2 } 
} 
END { 
    # Sort the items based on the date  
    n = asorti(count, indices)  
    for (i = 1; i <= n; i++) {  
        print indices[i], count[indices[i]]
    }
}' < file_name

このブロックは、すべてのレコードが処理された最後に実行されますEND

配列の配置は次のように変更されました。この投稿

答え3

次のスクリプトを使用できますawk

$ awk '
  { a[$1]+=$2 }
  END{ for(val in a) printf("%s %s\n", val, a[val]) }
' <(tail -n +2 sample.txt)

ただし、このアプローチでは、出力順序は維持されなくなります。データが日付番号順になっている場合、sort最後に簡単な操作を実行すると、出力サイズが再調整されます。

はい

サンプルデータを想定します。

$ cat sample.txt 
date            Value
01/01/2000     2
01/01/2000     2
01/02/2000     6
01/03/2000     5
01/03/2000     4

上記のスクリプトは、次のような結果を生成します。

$ awk '
  { a[$1]+=$2 }
  END{ for(val in a) printf("%s %s\n", val, a[val]) }
' <(tail -n +2 sample.txt)
01/02/2000 6
01/01/2000 4
01/03/2000 9

出力を実行すると、sortデータのサイズが変更されます。

$ awk '
  { a[$1]+=$2 }
  END{ for(val in a) printf("%s %s\n", val, a[val]) }
' <(tail -n +2 sample.txt)|sort
01/01/2000 4
01/02/2000 6
01/03/2000 9

元のファイルのヘッダーは、次のように再追加できます。

$ (head -n 1 sample.txt; awk '{a[$1]+=$2}END{for(val in a) printf("%s %s\n", val, a[val])}' <(tail -n +2 sample.txt)|sort)
date            Value
01/01/2000 4
01/02/2000 6
01/03/2000 9

読みやすいように少し拡張できます。

$ (
head -n 1 sample.txt
awk '
  { a[$1]+=$2 }
  END{ for(val in a) printf("%s %s\n", val, a[val]) }
' <(tail -n +2 sample.txt) | sort
)
date            Value
01/01/2000 4
01/02/2000 6
01/03/2000 9

アップデート#1

コメントの@StephaneChazelasからのフィードバックに基づいて、例をさらに簡素化しました。 this() を使用してtail ...ブロック内に移動すると、削除できます。最初の行をスキップします。awkNR==1{ next }sample.txt

| sortブロック内でも位置を移動しましたEND{...}sort日付に基づいてデータから生成された出力のサイズは引き続き調整されます。今呼び出し中なのでawk二重引用符で囲みます。awk/bin/sort

$ awk '
  NR==1{ print; next }
  { a[$1]+=$2 }
    END{ for(val in a) print val, a[val] | "sort" }
' sample.txt
)
date            Value
01/01/2000 4
01/02/2000 6
01/03/2000 9

答え4

私はPerlでこれをします:

perl -ane '$.==1 && do{$first=$_; next}; $k{$F[0]}+=$F[1]; END{foreach (keys(%k)){print "$_\t$k{$_}\n"}}' file

01/01/2000  4
01/03/2000  9
01/02/2000  6

このアプローチの利点は、行を時系列で並べ替える必要がないことです。

関連情報