각 열의 값을 합산하고 열 머리글을 바꿔야 하는 꽤 큰 csv 파일이 여러 개 있습니다.
예시 CSV:
col1,col2,col3
enabled,disabled,active
disabled,disabled,enabled
N/A,enabled,active
enabled,N/A,disabled
원하는 출력:
col1,2 enabled,1 disabled,1 N/A
col2,1 enabled,2 disabled,1 N/A
col3,1 enabled,1 disabled,2 active
실제 csv에는 더 많은 열과 행이 있으므로 파일을 자동으로 반복할 수 있으면 좋을 것입니다. 한 번에 한 열씩 수행하는 awk 프로그램 해킹을 생각해낼 수도 있지만, 전체 파일을 한 번에 처리할 수 있고 어디서부터 시작해야 할지 모르는 것을 선호합니다. 출력은 내가 포함시킨 정확한 형식일 필요는 없지만 적어도 유사해야 합니다.
답변1
$ cat tst.awk
BEGIN { FS=OFS="," }
NR==1 { numRows = split($0,keys); next }
{
for (i=1; i<=NF; i++) {
sum[i,$i]++
vals[$i]
}
}
END {
for (rowNr=1; rowNr<=numRows; rowNr++) {
printf "%s", keys[rowNr]
for (val in vals) {
printf "%s%d %s", OFS, sum[rowNr,val], val
}
print ""
}
}
$ awk -f tst.awk file
col1,1 disabled,2 enabled,1 N/A,0 active
col2,2 disabled,1 enabled,1 N/A,0 active
col3,1 disabled,1 enabled,0 N/A,2 active
아니면 더 유용할 수도 있습니다:
$ cat tst.awk
BEGIN { FS=OFS="," }
NR==1 { numRows = split($0,keys); next }
{
for (i=1; i<=NF; i++) {
sum[i,$i]++
vals[$i]
}
}
END {
printf "%s", "key"
for (val in vals) {
printf "%s%s", OFS, val
}
print ""
for (rowNr=1; rowNr<=numRows; rowNr++) {
printf "%s", keys[rowNr]
for (val in vals) {
printf "%s%d", OFS, sum[rowNr,val]
}
print ""
}
}
$ awk -f tst.awk file
key,disabled,enabled,N/A,active
col1,1,2,1,0
col2,2,1,1,0
col3,1,1,0,2
답변2
Miller와 매우 가까워질 수 있습니다.
mlr --icsvlite --odkvp put -q 'for(k,v in $*) { @count[k][v] += 1; } end {emit @count,"col"}' sample.csv
col=col1,enabled=2,disabled=1,N/A=1
col=col2,disabled=2,enabled=1,N/A=1
col=col3,active=2,enabled=1,disabled=1