![BASH: AWK는 CSV를 원하는 테이블로 전송합니다.](https://linux55.com/image/165518/BASH%3A%20AWK%EB%8A%94%20CSV%EB%A5%BC%20%EC%9B%90%ED%95%98%EB%8A%94%20%ED%85%8C%EC%9D%B4%EB%B8%94%EB%A1%9C%20%EC%A0%84%EC%86%A1%ED%95%A9%EB%8B%88%EB%8B%A4..png)
bash를 사용하여 .csv 파일을 원하는 테이블 형식으로 변환하는 데 어려움을 겪었습니다.
내 파일 o/p:
$ cat finalcount.csv
state,status,count
NW,CONGESTED,11
NW,CLEARED,9
ACT,CLEARED,7
ACT,CONGESTED,7
QLD,CLEARED,5
WA,CONGESTED,3
WA,CLEARED,2
VIC,CLEARED,3
VIC,CONGESTED,2
내가 원하는 O/P:
State Congested Cleared
ACT 7 7
NW 11 9
VIC 2 3
QLD - 5
답변을 공유하고 설명해주세요.
답변1
사용밀러:
$ mlr --icsvlite --opprint \
reshape -s status,count then unsparsify then reorder -e -f CLEARED finalcount.csv
state CONGESTED CLEARED
NW 11 9
ACT 7 7
QLD - 5
WA 3 2
VIC 2 3
GNU 데이터 통합열 순서를 제어하는 쉬운 방법은 없는 것 같지만 피벗 테이블(크로스탭이라고도 함)과 같은 작업에도 유용합니다.
datamash --header-in --filler=- -t, crosstab 1,2 unique 3 < finalcount.csv | csvformat -T
CLEARED CONGESTED
ACT 7 7
NW 9 11
QLD 5 -
VIC 3 2
WA 2 3
정말로 Awk를 사용해야 한다면 다음과 같이 작동할 것입니다:
awk -F, '
NR>1 {s[$1]}
$2 == "CONGESTED" {a[$1]=$3}
$2 == "CLEARED" {b[$1]=$3}
END {
printf "state\tcongested\tcleared\n";
for (k in s)
printf "%s\t%s\t%s\n", k, a[k]=="" ? "-" : a[k], b[k]=="" ? "-" : b[k]
}
' finalcount.csv
답변2
$ cat tst.awk
BEGIN { FS=","; OFS="\t" }
{ sub(/\r$/,"") }
NR > 1 {
states[$1]
statuses[$2]
vals[$1,$2] = $NF
}
END {
printf "%s", "state"
for (status in statuses) {
printf "%s%s", OFS, status
}
print ""
for (state in states) {
printf "%s", state
for (status in statuses) {
printf "%s%s", OFS, ((state,status) in vals ? vals[state,status] : "-")
}
print ""
}
}
.
$ awk -f tst.awk file
state CONGESTED CLEARED
QLD - 5
ACT 7 7
WA 3 2
NW 11 9
VIC 2 3
.
$ awk -f tst.awk file | column -s $'\t' -t
state CONGESTED CLEARED
QLD - 5
ACT 7 7
WA 3 2
NW 11 9
VIC 2 3