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)
出力インデックスの順序が混乱しますa
。https://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