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
나는 두 가지를 원합니다. 내림차순으로 정렬하고 과학 표기법에 없는 숫자를 변경하고 두 개의 부동 소수점을 사용합니다. 누구든지 나에게 조언을 해줄 수 있습니까?
답변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. 이를 수행하는 더 좋은 방법이 있지만 상점이 이미 입력에서 정렬되어 있으므로 배열이 전혀 필요하지 않습니다. 출력에서 상점이 동일한 방식으로 정렬되도록 한 번에 하나씩 처리하면 됩니다. 다시 읽으면 모든 데이터를 메모리에 저장한 다음 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