본문으로 건너뛰기
AZ Tools

CSV 파일을 망가뜨리지 않고 다루기

CSV는 컴퓨팅에서 가장 단순한 포맷처럼 보입니다. 값, 쉼표, 줄바꿈이 전부니까요. 그런데 실제로는 가장 많은 데이터를 조용히 망가뜨리는 포맷입니다. 단일한 표준이 없고 만드는 쪽마다 조금씩 다른 선택을 하기 때문입니다. 거의 모든 CSV 문제는 몇 가지 모호함 중 하나에서 나오며, 그것들을 이름 붙일 수 있게 되면 해결책은 자명해집니다.

값 안의 쉼표, 그리고 따옴표 규칙

값이 구분자를 포함하는 순간 포맷에는 이스케이프가 필요해지고, 관례는 그 필드를 큰따옴표로 감싸는 것입니다. 따옴표로 감싼 필드 안의 따옴표 문자는 두 번 씁니다. 이름 필드에 담긴 Smith, John 이 "Smith, John" 으로 나타나는 이유이고, 따옴표를 포함한 값에서 따옴표가 겹쳐 보이는 이유입니다 — 오타가 아니라 이스케이프 규칙입니다.

따라서 CSV 한 줄을 쉼표로 쪼개는 방식은, 아무리 솔깃해도 작동하지 않습니다. 올바른 파서는 지금 따옴표 안에 있는지를 추적하며, 따옴표로 감싼 필드에는 쉼표·따옴표는 물론 줄바꿈까지 합법적으로 들어갈 수 있습니다. 파일 중간부터 갑자기 열이 늘어난다면, 값 안에 이스케이프되지 않은 구분자가 있는 것이 거의 항상 원인입니다.

구분자가 언제나 쉼표인 것은 아닙니다

쉼표를 소수점으로 쓰는 지역에서는 스프레드시트가 CSV를 세미콜론으로 쓰는 일이 흔합니다. 그래서 한 컴퓨터에서 완벽하게 열리던 파일이 다른 컴퓨터에서는 한 열에 뭉쳐 들어갑니다. 탭도 널리 쓰이며, 값 안에 탭이 들어가는 경우가 드물다는 바로 그 이유로 더 안전합니다.

구분자는 파일 어디에도 선언되지 않기 때문에 도구가 추측해야 하고, 보통 후보들을 시험해 열 개수가 일관되게 나오는 쪽을 고릅니다. 가져오기가 어긋났을 때 가장 빨리 배제할 수 있는 것이 구분자이며, 내보내는 쪽을 직접 통제한다면 탭 구분 데이터가 이 부류의 문제를 통째로 피하게 해줍니다.

인코딩, 그리고 BOM을 원하는 스프레드시트

é 가 있어야 할 자리에 é 처럼 보이는 텍스트는 UTF-8 파일을 옛 단일바이트 인코딩으로 읽은 것입니다. CSV에는 인코딩 선언이 없어서 읽는 쪽이 지시를 받거나 추측해야 하는데, 잘못 추측하면 구조는 멀쩡한 채 비ASCII 문자만 전부 깨집니다 — 그래서 이 손상이 데이터베이스까지 그대로 살아 들어가는 일이 잦습니다.

주범은 대개 엑셀입니다. 많은 환경에서 파일이 UTF-8 BOM으로 시작하지 않으면 옛 코드페이지를 가정합니다. BOM을 쓰면 악센트 문자가 제대로 열리지만, 대신 파일 앞머리에 보이지 않는 몇 바이트가 붙고 일부 엄격한 파서는 그것을 첫 열 이름의 일부로 돌려줍니다. 이걸 미리 알면 혼란스러운 30분을 아낍니다.

스프레드시트가 조용히 고쳐 쓰는 값들

CSV에는 타입이 없습니다 — 전부 텍스트죠 — 그래서 읽는 쪽이 의미를 정하고, 스프레드시트는 이 일에 공격적입니다. 우편번호나 상품 코드를 숫자로 읽으면 앞자리 0이 사라집니다. 긴 식별자는 지수 표기로 바뀝니다. 날짜처럼 생긴 문자열은 기기의 로케일에 맞춰 다시 서식이 매겨지고, 같은 파일이 두 사무실에서 다른 결과를 내는 이유가 이것입니다.

안전한 방법은 나중에 고치는 것이 아니라 가져오는 시점에 그런 열을 텍스트로 지정하는 것입니다. 변환이 일어난 뒤에는 원래 숫자가 이미 사라졌으니까요. 문자 그대로가 중요한 것 — 식별자, 전화번호, 각종 코드 — 에 대해서는 자동 타입 인식을 나중에 바로잡을 대상이 아니라 애초에 꺼야 할 기능으로 취급하세요.

CSV를 다른 형태로 옮기기

JSON으로 바꾸면 실제 타입과 중첩 구조가 생겨 검증이 훨씬 쉬워집니다 — 다만 위의 모호함들을 명시적으로 해결하도록 강제하므로, 늦게보다 일찍 해두는 편이 낫습니다. 반대 방향으로 CSV에서 SQL 삽입문을 만들 때는 같은 이스케이프 문제가 더 위험한 형태로 돌아옵니다. 값 안의 따옴표는 CSV가 아니라 SQL 기준으로 이스케이프해야 합니다.

CSV를 믿기 전에 확인할 짧은 점검표:

  • 파싱 전에 구분자를 확인한다 — 쉼표, 세미콜론, 탭 중 무엇인지.
  • 인코딩을 확인하고, 엑셀로 갈 파일이면 BOM을 붙인다.
  • 구분자로 단순히 쪼개지 말고 따옴표로 감싼 필드를 존중한다.
  • 식별자 성격의 열은 텍스트로 가져와 앞자리 0을 지킨다.
  • 변환 후에는 앞 몇 줄이 아니라 행·열 개수를 확인한다.

관련 도구