awkを使用した販売レポートの生成

awkを使用した販売レポートの生成

awkスクリプトを使用して各店舗の販売レポートを作成しようとしています。データセットはcsv形式で、45の店舗があります。データの例は次のとおりです。

Store,Store_name,Date,Year,Weekly_Sales,Holiday_Flag,Temperature,Fuel_Price,CPI,Unemployment
1,Store1,05-02-2010,2010,1643690.9,No,42.31,2.572,211.0963582,8.106
1,Store1,12-02-2010,2010,1641957.44,Yes,38.51,2.548,211.2421698,8.106
...
...
45,Store45,12-10-2012,2012,734464.36,No,54.47,4,192.3272654,8.667
45,Store45,19-10-2012,2012,718125.53,No,56.47,3.969,192.3308542,8.667

次のコードを使用して店舗をグループ化し、個々のグループ履歴を要約します。

#!/usr/bin/awk -f

awk BEGIN {F=","} {a[$2]+=$5;}END{for(i in a)print i", "a[i];}

上記のコードの出力は次のとおりです。

Store1, 2.22403e+08
...
...
Store45, 1.12395e+08

2つ欲しいです。降順に並べ替え、科学表記にない数字を変更し、2つの浮動小数点を使用します。誰でも私にアドバイスを与えることができますか?

答え1

printf を使用して出力形式を指定します。たとえばprintf "%s, %.2f\n", i, a[i]。そして、入力をパイピングしてsort出力を整列します。たとえば、

-V「バージョン」ソート(「ナチュラルソート」とも呼ばれます)のGNUソートオプションを使用して、店舗名でソートします。

$ awk -F, '{a[$2]+=$5;}END{for(i in a)printf "%s, %.2f\n", i, a[i]}' file.csv | sort -V -k1,1
Store1, 3285648.34
Store45, 1452589.89

総販売量に基づいてソート:

$ awk -F, '{a[$2]+=$5;}END{for(i in a)printf "%s, %.2f\n", i, a[i]}' file.csv | sort -k2,2
Store45, 1452589.89
Store1, 3285648.34

答え2

ループを使用すると、for (i in a)出力インデックスの順序が混乱しますahttps://www.gnu.org/software/gawk/manual/gawk.html#Scanning-an-Array。これを行うより良い方法がありますが、ストアはすでに入力からソートされているため、配列はまったく必要ありません。出力で店舗が同じように整列されるように、一度に1つずつ処理するだけです。再読み込みすると、すべてのデータをメモリに保存してからENDセクションのすべてのストアを繰り返す必要がなく、メモリと実行速度がより効率的です。

$ cat tst.awk
BEGIN {
    FS = ","
    ofmt = "%s, %0.2f\n"
}
$2 != store {
    if ( NR > 2 ) {
        printf ofmt, store, tot
    }
    store = $2
    tot = 0
}
{ tot += $5 }
END {
    printf ofmt, store, tot
}

$ awk -f tst.awk file
Store1, 3285648.34
Store45, 1452589.89

関連情報