본문 바로가기

엑셀이 CSV를 망가뜨리는 이유

우편번호의 앞자리 0이 사라지고, 제품 코드가 날짜로 바뀌고, 긴 식별 번호가 조용히 반올림됩니다. 이 일은 저장할 때가 아니라 열 때 일어나며, 그래서 많은 사람이 무엇이 잘못됐는지 끝내 알아내지 못합니다.

최종 검토:

손상은 파일을 열 때 일어납니다

이 문제를 진단하기 어렵게 만드는 부분이 바로 여기입니다. CSV는 텍스트 파일입니다. 안의 모든 값은 글자일 뿐이고, 각 값이 무엇을 뜻하는지는 파일 어디에도 적혀 있지 않습니다. Excel은 CSV를 열 때 열마다 유형을 추측하고, 그에 맞게 값을 변환한 뒤, 그 순간부터 변환된 버전을 들고 있습니다. 파일을 저장하면 변환된 값이 그대로 기록됩니다.

즉 원래 파일은 멀쩡했는데 저장한 파일은 망가졌고, 그 과정에서 아무런 경고도 없었습니다. 사람들은 내보내기가 잘못됐다고 생각해 다시 내보내지만 결과는 같습니다. 손상은 다운로드한 뒤 자기 컴퓨터에서 일어나고 있기 때문입니다.

손상을 일으키는 네 가지 변환

앞자리 0이 사라집니다. 01234 같은 우편번호, 프랑스 도 코드, 계좌 번호, 0으로 시작하는 전화번호는 모두 숫자처럼 보이기 때문에 0이 의미 없는 것으로 버려집니다. 하지만 의미 없는 0이 아니라 식별 번호의 일부입니다.

긴 숫자가 반올림됩니다. 스프레드시트는 숫자를 유효 숫자 약 15자리의 부동소수점으로 저장하기 때문에, 주문 번호, 신용카드 번호, IMEI, 64비트 식별자는 조용히 반올림되어 마지막 자릿수가 0이 됩니다. 셀에는 숫자처럼 보이는 값이 있지만 틀린 숫자입니다.

날짜처럼 보이는 것은 모두 해당 지역의 표기 방식으로 바뀝니다. 03/05는 어떤 나라에서는 3월, 다른 나라에서는 5월이라, 같은 파일을 두 사무실에서 열면 서로 다른 데이터가 됩니다. 더 나쁜 것은 원래 날짜가 아니었던 값까지 변환된다는 점입니다. SEPT1 같은 유전자 이름이 날짜로 바뀌는데, 이 문제가 워낙 끈질겨서 유전학자들은 결국 싸우기를 포기하고 유전자 이름을 바꿨습니다.

악센트가 있는 글자가 깨집니다. CSV에는 문자 인코딩 정보가 담기지 않기 때문에, UTF-8로 저장한 파일을 구식 코드 페이지로 읽거나 그 반대로 하면, 악센트가 들어간 이름이 있는 행만 정확히 골라서 깨집니다.

해결책: 열지 말고 가져오기

중요한 CSV는 절대 더블클릭하지 마세요. 더블클릭은 Excel에게 추측할 권한을 주는 것이고, Excel은 자신 있게 추측합니다.

대신 데이터 → 텍스트/CSV에서를 사용하세요. 가져오기 대화 상자에서는 무엇이든 분석되기 전에 열마다 유형을 지정할 수 있습니다. 우편번호 열과 식별자 열을 텍스트로 지정하면 파일에 있는 그대로 들어옵니다. 인코딩과 구분 기호도 추측에 맡기지 않고 직접 지정할 수 있습니다. 20초면 되고, 이것이 해결책의 전부입니다.

Google 스프레드시트도 마찬가지입니다. 파일 → 가져오기에서 “텍스트를 숫자, 날짜, 수식으로 변환”을 끄세요. LibreOffice Calc는 기본적으로 열 유형 대화 상자를 보여 주는데, LibreOffice가 확실히 더 얌전하게 동작하는 몇 안 되는 부분입니다.

가져오기 전에 먼저 확인하기

이미 문제가 생겼다면, 스프레드시트가 손대지 않은 상태로 파일을 보는 것이 가장 유용한 첫 단계입니다. CSV 보기는 바이트에 적힌 그대로 값을 보여 줍니다. 앞자리 0도 있고, 긴 숫자도 온전하고, 날짜도 원래 적힌 텍스트 그대로입니다. 이것만 보면 내보내기가 잘못됐는지 가져오기가 잘못됐는지 바로 알 수 있습니다.

CSV가 스스로 밝히지 않는 두 가지도 알 수 있습니다. 하나는 구분 기호로, 쉼표, 세미콜론, 탭 중 하나입니다. 유럽 지역 설정에서는 쉼표가 소수점 기호라서 세미콜론으로 내보냅니다. 다른 하나는 인코딩입니다. 가져오기 전에 이 둘을 알면 남은 추측은 대부분 사라집니다.

CSV를 만드는 쪽이라면

내보내는 쪽에서 몇 가지만 정하면 이후의 문제를 모두 막을 수 있습니다.

Windows의 Excel에서 열 파일이라면 바이트 순서 표시(BOM)가 있는 UTF-8로 저장하세요. Excel은 이 표시로 UTF-8을 감지하며, 없으면 악센트 글자를 깨뜨립니다. BOM을 넣는 것이 골칫거리가 아니라 올바른 선택인 드문 경우입니다.

잘못 읽힐 수 있는 필드는 모두 따옴표로 묶고, 식별자 열은 항상 묶으세요. 따옴표로 묶어도 Excel이 열 때 변환하는 것을 막지는 못하지만, 다른 모든 프로그램에는 의도가 분명하게 전달됩니다.

CSV를 아예 쓰지 않는 것도 고려하세요. 받는 쪽이 JSON이나 진짜 스프레드시트를 받을 수 있다면, 둘 다 유형을 명시적으로 담고 있어서 이런 문제가 전혀 없습니다. CSV의 장점은 모든 프로그램이 읽을 수 있다는 것이고, 약점은 그 내용이 무엇을 뜻하는지 어떤 프로그램도 합의하지 않는다는 것입니다.

자주 묻는 질문

저장한 뒤에 손상을 되돌릴 수 있나요?

확실하게는 불가능합니다. 사라진 앞자리 0과 반올림된 자릿수는 없어졌고, 파일에는 이를 복원할 근거가 남아 있지 않습니다. 원본 소스에서 다시 내보내세요. 원래 내보낸 파일을 손대지 않고 보관해 둘 가치가 있는 이유입니다.

CSV가 왜 긴 열 하나로 열리나요?

구분 기호가 스프레드시트가 기대하는 것과 맞지 않기 때문입니다. 보통 세미콜론 파일을 쉼표를 쓰는 지역 설정에서 열었거나 그 반대인 경우입니다. 가져오기 대화 상자에서 구분 기호를 지정할 수 있으며, 시스템의 지역 설정을 바꾸는 것보다 빠릅니다.

첫 번째 열 이름 앞에 붙은 이상한 문자는 뭔가요?

바이트 순서 표시(BOM)가 인코딩 힌트가 아니라 텍스트로 읽힌 것입니다. Excel에서 악센트 글자를 바로잡아 주는 바로 그 표시라서, 유용하면서도 성가십니다. 제대로 된 CSV 파서는 대부분 자동으로 제거합니다.

CSV 표준이 있나요?

대부분의 도구가 하는 방식을 설명한 2005년의 권고 사양이 있을 뿐이고, 다르게 동작하는 소프트웨어도 많습니다. 그래서 구분 기호, 따옴표, 줄 끝, 인코딩이 제각각이며, 가정하지 않고 감지하는 것만이 실제 파일에서 통하는 유일한 방법입니다.

텍스트 편집기에서 한 행이 왜 여러 줄로 나뉘나요?

따옴표로 묶은 필드에는 줄바꿈이 들어갈 수 있기 때문입니다. 주로 주소 필드가 그렇습니다. 레코드는 여전히 한 행이지만, 줄바꿈 기준으로 파일을 나누는 프로그램은 바로 그런 행을 망가뜨립니다. 쉼표나 줄바꿈으로 나눠서 CSV를 읽으면 안 되는 이유입니다.