여러 합계를 계산해야 합니다. 입력 파일은 다음과 같습니다.
DATE|NATION|CITY|FILES|REVENUE|FREQUENCY|INVESTMENT
20170807|USA|VIRGINIA|TIMES|1919150|1779|282075
20170807|USA|NYC|ROADS|92877|41|1599
20170808|USA|PENS|ROADS|133001|7|1
20170808|USA|NYC|TIMES|361625|1592|0
- uniq(날짜)로 1달러당 5달러 합계
- $4=="TIMES"인 각 유니크의 합계 $5
- 각 유니크의 합계는 $5입니다. 여기서 $4=="ROADS"
- 각 유니크의 합계는 $5입니다. 여기서 $4=="ROADS" 및 $3=="NYC"
- $1 열 기준으로 정렬
내 예상 결과
DATE|REV|TIMES|ROADS|ROADS&NYC
20170807|2012027|1919150|92877|92877
20170808|494626|361625|133001|0
1개의 열을 기준으로 합산하는 방법만 알고 있습니다.
awk -F"|" '{FS=OFS="|"}{col[$1]+=$5} END {for (i in col) print i, col[i]}'
답변1
awk
해결책 은 다음과 같습니다 .
awk -F'[|]' 'NR>1 { I[$1]+=$5 }
($4=="TIMES") { T[$1]+=$5 }
($4=="ROADS") { R[$1]+=$5 }
($4=="ROADS" && $3=="NYC"){ RN[$1]+=$5 }
END{ print "DATE|REV|TIMES|ROADS|ROADS&NYC"
for (x in I) printf"%d|%d|%d|%d|%d\n", x, I[x], T[x], R[x], RN[x]
}' infile.txt
답변2
복잡한멍하니목표 달성을 위한 솔루션:
awk 'BEGIN{ FS=OFS="|" }NR==1{ next }{ sum[$1]+=$5 }
$4=="TIMES"{ d[$1]["t"]+=$5 }
$4=="ROADS"{ d[$1]["r"]+=$5 }$3=="NYC" && $4=="ROADS"{ d[$1]["r&n"]+=$5 }
END{ print "DATE|REV|TIMES|ROADS|ROADS&NYC";
for(i in d) print i, sum[i], int(d[i]["t"]), int(d[i]["r"]), int(d[i]["r&n"]) }' file
산출:
DATE|REV|TIMES|ROADS|ROADS&NYC
20170807|2012027|1919150|92877|92877
20170808|494626|361625|133001|0
답변3
여러 배열이 필요하지 않습니다. 필드에 인덱스를 쓰고 모든 것을 합산한 다음 원하는 합계 인덱스만 반환하고 NULL
필드가 표시되도록 0을 추가하면 됩니다.
awk 'BEGIN{FS=OFS="|"; print "DATE|REV|TIMES|ROADS|ROADS&NYC"}
NR>1{rev[$1]+=$5; sum[$1$4]+=$5; sum[$1$4$3]+=$5}
END{for (dt in rev) print dt, rev[dt], sum[dt"TIMES"]+0, sum[dt"ROADS"]+0, sum[dt"ROADSNYC"]+0}' file
가독성도 더 좋고...
답변4
사용밀러( mlr
):
mlr --csv --fs pipe \
reshape -s FILES,REVENUE then \
put '$tmp=$ROADS; $REV=$ROADS+$TIMES' then \
reshape -s CITY,tmp then \
stats1 -a sum -g DATE -f REV,TIMES,ROADS,NYC then \
unsparsify --fill-with 0 file.csv
질문의 데이터가 주어지면 다음이 생성됩니다.
DATE|REV_sum|TIMES_sum|ROADS_sum|NYC_sum
20170807|2012027|1919150|92877|92877
20170808|494626|361625|133001|0
첫 번째 작업( reshape
작업)은 필드에서 값을 가져오고 의 FILES
값을 사용하여 해당 필드에서 새 필드를 생성합니다 REVENUE
. 이는 다음과 같은 레코드를 제공합니다(일부 레코드에는 특정 필드가 누락되어 있으므로 세 개의 별도 컬렉션에 있음).
날짜 | 국가 | 도시 | 빈도 | 투자하다 | 연대 |
---|---|---|---|---|---|
20170807 | 미국 | 여자 이름 | 1779 화 | 282075 | 1919150 |
날짜 | 국가 | 도시 | 빈도 | 투자하다 | 방법 |
---|---|---|---|---|---|
20170807 | 미국 | 뉴욕시 | 41 | 1599년 | 92877 |
20170808 | 미국 | 펜 | 7 | 1 | 133001 |
날짜 | 국가 | 도시 | 빈도 | 투자하다 | 연대 |
---|---|---|---|---|---|
20170808 | 미국 | 뉴욕시 | 1592 화 | 0 | 361625 |
이 put
작업은 REV
합계 값을 합산하여 각 레코드의 필드를 계산합니다(이 중 하나는 각 레코드에서 누락됩니다). 또한 나중에 총 수익을 계산하는 데 사용될 임시 값도 계산합니다. 그 후에는 다음과 같은 데이터가 있습니다.ROADS
TIMES
ROADS
NYC
put
날짜 | 국가 | 도시 | 빈도 | 투자하다 | 연대 | 회전 속도 |
---|---|---|---|---|---|---|
20170807 | 미국 | 여자 이름 | 1779 화 | 282075 | 1919150 | 1919150 |
날짜 | 국가 | 도시 | 빈도 | 투자하다 | 방법 | tmp | 회전 속도 |
---|---|---|---|---|---|---|---|
20170807 | 미국 | 뉴욕시 | 41 | 1599년 | 92877 | 92877 | 92877 |
20170808 | 미국 | 펜 | 7 | 1 | 133001 | 133001 | 133001 |
날짜 | 국가 | 도시 | 빈도 | 투자하다 | 연대 | 회전 속도 |
---|---|---|---|---|---|---|
20170808 | 미국 | 뉴욕시 | 1592 화 | 0 | 361625 | 361625 |
두 번째 방법은 합계를 계산하는 reshape
더 쉬운 방법을 제공합니다 .ROADS
NYC
날짜 | 국가 | 도시 | 빈도 | 투자하다 | 연대 | 회전 속도 |
---|---|---|---|---|---|---|
20170807 | 미국 | 여자 이름 | 1779 화 | 282075 | 1919150 | 1919150 |
20170808 | 미국 | 뉴욕시 | 1592 화 | 0 | 361625 | 361625 |
날짜 | 국가 | 빈도 | 투자하다 | 방법 | 회전 속도 | 뉴욕시 |
---|---|---|---|---|---|---|
20170807 | 미국 | 41 | 1599년 | 92877 | 92877 | 92877 |
날짜 | 국가 | 빈도 | 투자하다 | 방법 | 회전 속도 | 펜 |
---|---|---|---|---|---|---|
20170808 | 미국 | 7 | 1 | 133001 | 133001 | 133001 |
그런 다음 이 stats1
명령을 사용하여 다음과 같은 방식으로 그룹화된 필수 필드의 합계를 계산합니다 DATE
.
날짜 | 총 속도 | TIMES_sum | ROADS_sum | 뉴욕섬 |
---|---|---|---|---|
20170807 | 2012027 | 1919150 | 92877 | 92877 |
날짜 | 총 속도 | TIMES_sum | ROADS_sum |
---|---|---|---|
20170808 | 494626 | 361625 | 133001 |
그런 다음 다른 레코드에 있는 필드가 누락된 모든 레코드에 해당 필드의 값으로 0이 추가되도록 최종적으로 희소화합니다.
날짜 | 총 속도 | TIMES_sum | ROADS_sum | 뉴욕섬 |
---|---|---|---|---|
20170807 | 2012027 | 1919150 | 92877 | 92877 |
20170808 | 494626 | 361625 | 133001 | 0 |