.csv 파일의 일부 행에서 열이 누락되는 문제 해결

.csv 파일의 일부 행에서 열이 누락되는 문제 해결

현재 여러 병합된 .csv 파일의 데이터를 처리하고 있습니다. 불행하게도 이러한 병합은 때때로 잘못된 경우가 있습니다.

이 예는 이를 가장 잘 설명합니다.

"var1", "var2", "var3", "var4", "var5"
"2001", "노란색", "123", "abc", "bcdefg"
"2002", "노란색", "123", "abw", "asdfkl"
"2001", "녹색", "abe"
"2002", "녹색", "abp"
"2001", "파란색", "324", "abx", "badsf"
"2002 ","파란색","231","abl","cpq"

따라서 3행과 4행에서는 var3 및 var5의 값이 누락되었습니다. 변수(열)이 누락되는 오류는 항상 동일합니다.

내 CSV가 다음과 같이 보이길 원합니다.

"var1", "var2", "var3", "var4", "var5"
"2001", "노란색", "123", "abc", "bcdefg"
"2002", "노란색", "123", "abw", "asdfkl"
"2001", "녹색", "abe",
"2002", "녹색", "abp",
"2001", "파란색", "324", "abx", "badsf"
"2002","블루","231","abl","cpq"

따라서 이제 행 3과 4는 실제로 var3 및 var5에 대한 누락된 값입니다. 이 경우 오류는 "녹색"에서 항상 발생하는 것은 아니지만 다른 그룹에서도 발생할 수 있습니다.

내 생각은 행의 열을 검색하고 열 수가 헤더의 열 수("var1", "var2" 등)와 다른 경우 새 빈 열을 추가하는 것입니다.

여러 다른 파일에 대해 이 작업을 수행해야 하지만, 일단 수행 방법을 알아내고 나면 bash 스크립트 루프를 사용할 수 있을 것 같습니다.

[편집]: 명확히 하고 싶습니다. 데이터 세트가 상당히 큽니다. 최소 19개의 변수(열)가 있습니다. (확인해야 할 또 다른 파일에는 60개가 넘는 변수가 있습니다.)

이제 awk를 사용하는 솔루션을 고려 중입니다. 이 같은:

awk '{ if (NF<19) {$7=$7","#NA","#NA}}' 파일 1 > 파일 2

19열이 없으면(있어야 함) 7열 뒤에 2개의 열을 삽입해야 합니다. 나중에 시도해 볼 것입니다 ...

답변1

생각나는 가장 간단한 방법은 줄을 쉼표로 나누고 쉼표가 두 개만 있는 곳에 추가 쉼표를 삽입하는 것입니다. 명백한 한계는 실제 값에 쉼표가 있으면 이것이 깨진다는 것입니다.

$ cat test.csv | sed -r 's/^([^,]*),([^,]*),([^,]*)$/\1,\2, ,\3, /g'
"var1", "var2", "var3", "var4", "var5"
"2001", "yellow", "123", "abc", "bcdefg"
"2002", "yellow", "123", "abw", "asdfkl"
"2001", "green", , "abe", 
"2002", "green", , "abp", 
"2001", "blue", "324", "abx", "badsf"
"2002", "blue", "231", "abl", "cpq"

좀 더 일반적인 내용을 위해 Python 스크립트를 작성할 수도 있습니다(CSV 기능내장). 예를 들어 stdin에서 CSV를 읽고 stdout으로 출력하려면 다음을 수행합니다.

#!/usr/bin/env python
import sys
import csv

missing = [3, 5]  # 1-indexed positions of missing values
missing.sort()  # enforce the increasing order
reader = csv.reader(sys.stdin, delimiter=',', skipinitialspace=True)
writer = csv.writer(sys.stdout)
header = next(reader)  # get first row (header)
writer.writerow(header)  # write it back
for row in reader:
    if len(row) < len(header):
        # row shorter than header -> insert empty strings
        # inserting changes indices so `missing` must be sorted
        for idx in missing:
            row.insert(idx - 1, '')
    writer.writerow(row)

실제 CSV 파서를 사용하면 값 및 기타 극단적인 경우에 쉼표나 따옴표를 올바르게 처리한다는 이점이 있습니다. 출력 형식도 올바른 CSV이지만 사용자의 형식과 약간 다릅니다.

$ cat test.csv | python test.py 
var1,var2,var3,var4,var5
2001,yellow,123,abc,bcdefg
2002,yellow,123,abw,asdfkl
2001,green,,abe,
2002,green,,abp,
2001,blue,324,abx,badsf
2002,blue,231,abl,cpq

보시다시피 쉼표 뒤에는 추가 따옴표나 공백이 없습니다. 정말로 필요하다면 작성자를 위해 CSV 언어를 구성하는 것을 고려해 보겠습니다.

관련 정보