CSV는 4줄인데 데이터가 2행인 이유: 셀 안 줄바꿈부터 확인하세요
파일의 줄 수를 세고 헤더 한 줄을 빼는 방법은 셀 안에 줄바꿈이 없는 경우에만 데이터 개수와 맞을 수 있습니다. CSV에서 큰따옴표로 묶인 필드는 줄바꿈을 포함할 수 있습니다.
원인
텍스트의 물리적인 줄과 CSV 파서가 해석한 논리적인 레코드는 다릅니다. 헤더 포함 여부도 구별해야 합니다. 이 글은 RFC4180이 설명하는 쉼표 구분·큰따옴표 인용 방식으로 만든 예제입니다. 모든 CSV 변형이 동일한 형식을 사용한다는 뜻은 아닙니다. RFC4180
재현
03-multiline.csv는 아래 내용을 담습니다. 줄바꿈은 CRLF이며 A1 메모의 두 줄은 하나의 셀입니다.
id,memo
A1,"첫 줄
둘째 줄"
A2,"쉼표, 따옴표 ""예"""
눈에 보이는 물리 줄은 4개입니다. 그러나 CSV로 읽으면 헤더 1개와 데이터 2개, 총 3개 레코드입니다. 마지막 메모에는 쉼표와 따옴표가 있지만 열은 2개를 유지해야 합니다.
import csv
from pathlib import Path
path = Path('03-multiline.csv')
text = path.read_bytes().decode('utf-8')
with path.open(encoding='utf-8', newline='') as f:
rows = list(csv.reader(f, strict=True))
print(len(text.splitlines()), len(rows), len(rows) - 1)
print([len(r) for r in rows])
실행 결과는 4 3 2, 열 수 목록은 [2, 2, 2]입니다. 마지막 물리 줄을 단순 split(',')로 나누면 잘못된 3개 조각이 됩니다.
해결
파일을 줄별·쉼표별로 직접 잘라 표를 만들지 말고 인용 문법을 지원하는 파서를 사용합니다. Python에서는 파일을 newline=''로 열어 CSV 파서가 줄바꿈을 처리하도록 합니다. Python csv 공식 문서
다시 내보낼 때도 CSV writer로 메모의 줄바꿈·쉼표·따옴표를 보존합니다. 03-normalized.csv는 파싱한 값을 writer로 저장한 사본이며 다시 읽은 셀 값이 원본과 같음을 확인했습니다. 보기 좋게 한다는 이유로 메모 줄바꿈이나 쉼표를 삭제하지 않습니다.
행 수를 표시하는 도구라면 헤더 포함 레코드 3, 데이터 레코드 2, 물리 줄 4처럼 각각 이름을 붙여야 합니다. 첫 줄이 헤더인지는 사용자가 지정하게 합니다.
한계
닫히지 않은 따옴표가 있는 오류 예제는 정상 CSV와 다릅니다. 이번 strict=True 파서에서 오류로 거부되는 것을 확인했습니다. 구조 오류가 있으면 확정 데이터 행 수 대신 오류를 보여줘야 합니다. 단, 이 설정만으로 모든 CSV 문법·열 수 오류가 검출되는 것은 아니며 열 수 일치 등은 별도로 확인해야 합니다.
빈 레코드와 빈 문자열 셀, 마지막 줄바꿈의 존재도 행 수 표기에 영향을 줄 수 있습니다. 예제의 규칙을 다른 프로그램의 집계 결과와 비교할 때는 헤더·빈 행·구분자·인용 규칙을 먼저 맞추세요.
검토일: 2026-10-18. 로컬 재현: Python 3.9.6·합성 데이터. Excel GUI는 실행하지 않았으며 이 글의 실행 결과는 Python 파서 기준입니다.
AI 보조 작성: AI로 초안과 예제 코드를 만들고 로컬 실행으로 레코드 수·셀 값 보존을 검증했습니다. 실제 사용자 파일은 사용하지 않았습니다.