두 CSV 파일을 비교하고 무엇이 바뀌었는지 찾는 방법
두 CSV 파일을 비교하는 가장 빠른 방법은 둘 다 나란히 보여주는 diff 도구에 붙여넣고, 열을 정렬하고, 강조 표시된 행을 읽는 것입니다. 비교는 쉬운 부분입니다. 사람들을 괴롭히는 것은 노이즈입니다. 재정렬된 내보내기, 쉼표 대신 세미콜론, 또는 누군가 따옴표로 감싼 값 때문에 같은 데이터를 담은 두 파일이 공통점이 전혀 없는 것처럼 보일 수 있습니다.
이 가이드는 깔끔하고 신뢰할 수 있는 CSV diff를 얻는 방법을 설명합니다. 동등한 두 내보내기가 문서상으로 멀어지는 이유, 알아둘 가치가 있는 방법, 그리고 따라 할 수 있는 실제 예제를 살펴보겠습니다. 도구만 원한다면, CSV 비교 페이지가 브라우저에서 이 모든 것을 처리합니다.
CSV 파일이 의외로 비교하기 어려운 이유
CSV는 단순해 보이지만 하나의 엄격한 표준이 없습니다. 가장 가까운 것이 RFC 4180이지만, 현실의 많은 파일은 이를 따르지 않습니다. 같은 테이블의 두 내보내기는 정확히 같은 데이터를 설명하면서도 구분자, 따옴표, 줄 끝, 행 순서가 다를 수 있습니다. 일반 텍스트 diff는 그런 것을 전혀 모르므로 모든 것을 표시합니다.
시작하기 전에 결정해야 할 핵심은 이것입니다. 행 순서가 당신에게 중요한가요? 이름으로 정렬된 데이터베이스 내보내기와 ID로 정렬된 같은 내보내기는 동일한 레코드 집합을 담고 있지만, 줄 diff는 거의 모든 행을 빨강과 초록으로 칠합니다. 행에 안정적인 키(ID 열)가 있다면 두 파일을 먼저 그 키로 정렬하면 diff가 다시 읽을 수 있게 됩니다.
| diff에서 보이는 것 | 실제 변경인가? | 해야 할 일 |
|---|---|---|
| 행의 순서가 다름 | 아니오, 데이터가 같은 집합이라면 | 두 파일을 키 열로 정렬하세요 |
| 쉼표 vs 세미콜론 구분자 | 아니오, 같은 필드 | 하나의 구분자로 정규화하세요 |
Ada vs "Ada" | 아니오, 여기서 따옴표는 선택적 | 따옴표를 정규화하세요 |
| CRLF vs LF 줄 끝 | 아니오 | 줄 끝을 정규화하세요 |
| 끝에 있는 빈 줄 | 아니오 | 잘라내세요 |
| 셀 값이 바뀜 | 예 | 조사하세요, 이것은 실제입니다 |
구분자 행은 특히 지역 간에 많은 사람을 걸려 넘어지게 합니다. 많은 유럽 로케일은 쉼표가 소수점 구분자이기 때문에 세미콜론을 사용합니다. 같은 데이터, 다른 구분자입니다. 브라우저와 도구가 표 형식 텍스트를 어떻게 읽는지에 대한 세부 사항을 원한다면, 브라우저에서 파일 읽기에 관한 MDN의 노트가 유용한 출발점입니다.
CSV를 비교하는 네 가지 방법과 각각을 언제 쓸지
하나의 가장 좋은 방법은 없습니다. 파일의 크기와 행 순서가 중요한지에 따라 다릅니다. 일반적인 옵션을 비교하면 다음과 같습니다.
| 방법 | 가장 적합한 경우 | 수고 | CSV를 이해하는가? |
|---|---|---|---|
| 눈으로 확인 | 아주 작은 파일, 몇 줄 | 낮음 | 아니오, 당신이 파서입니다 |
| 온라인 diff 도구 | 빠른 확인, 어디서든 붙여넣기 | 낮음 | 행별로, 예 |
| 스프레드시트 앱 | 시각적 검토, 수식, 필터링 | 중간 | 예, 하지만 수동 |
명령줄 (sort, csvkit) | 큰 파일, 스크립팅, 키 기반 비교 | 중간 | 예, 먼저 정렬하면 |
대부분의 사람에게는 브라우저 도구가 속도 면에서 이깁니다. 설치할 것이 없고, 다운로드나 데이터베이스 클라이언트에서 바로 내보내기를 붙여넣을 수 있습니다. 함정은 행 순서와 구분자 노이즈인데, 다음에서 다룹니다. 아주 큰 파일에는 명령줄의 csvkit을 배울 가치가 있습니다.
가장 빠른 깔끔한 비교, 단계별로
누군가 두 내보내기를 건네며 "뭐가 다른가요?"라고 물을 때 제가 사용하는 루틴입니다. 1분도 걸리지 않습니다.
- 두 파일이 같은 구분자를 사용하고 같은 헤더 행을 가지고 있는지 확인합니다.
- 행 순서가 중요하지 않다면, 먼저 두 파일을 키 열로 정렬합니다.
- CSV 비교 도구를 엽니다.
- 왼쪽에 원본을, 오른쪽에 새 버전을 붙여넣습니다.
- 결과를 읽습니다. 초록은 추가된 행, 빨강은 제거된 행이며, 변경된 셀은 각 색으로 하나씩 표시됩니다.
행이 정렬되지 않은 경우 2단계가 모든 핵심입니다. 두 파일이 같은 방식으로 정렬되면, 강조 표시할 것은 실제로 바뀐 행뿐입니다. 우리의 diff 엔진은 Google의 diff-match-patch를 기반으로 하며, 먼저 줄 단위로 비교하므로 긴 파일에서도 빠르게 유지됩니다.
실제 예제
사용자 테이블의 변경을 검토하고 있다고 가정합시다. 변경 전:
id,name,role,seats
7,Ada Lovelace,editor,3
8,Alan Turing,viewer,1
그리고 다른 행 순서로 내보낸 변경 후:
id,name,role,seats
8,Alan Turing,viewer,1
7,Ada Lovelace,admin,5
이것을 일반 줄 diff에 넣으면 두 데이터 행 모두 바뀐 것처럼 보입니다.
위치를 맞바꿨기 때문입니다. 둘 다 id 열로 정렬하면 실제 이야기는 짧습니다:
| 행 (id 기준) | 열 | 이전 | 이후 | 변경 |
|---|---|---|---|---|
| 7 | role | editor | admin | 수정됨 |
| 7 | seats | 3 | 5 | 수정됨 |
| 8 | — | — | — | 변경 없음 (이동만 함) |
실제 편집은 하나뿐입니다: Ada의 역할과 좌석 수가 바뀌었습니다. Alan의 행은 이동만 했습니다.
editor에서 admin으로의 그 승격은 검토에서 잡고 싶은 바로 그런 종류이며,
diff가 잘못 변경으로 표시한 행들 아래에 묻혀 있으면 놓치기 쉽습니다.
명령줄에서 행 순서 노이즈 없애기
파일이 이미 디스크에 있고 행에 고유한 순서가 없다면, 같은 "먼저 정렬" 아이디어가 두 개의 짧은 명령으로 작동합니다. 헤더를 그대로 두고 나머지를 정렬합니다:
(head -1 old.csv; tail -n +2 old.csv | sort) > old.sorted.csv
(head -1 new.csv; tail -n +2 new.csv | sort) > new.sorted.csv
diff old.sorted.csv new.sorted.csv
이제 diff는 정말로 바뀐 행만 보고합니다. 두 파일이 같은 순서이기 때문입니다.
열 순서까지 무시하는 키 기반 비교에는 csvkit의 csvsort와 csvjoin이
더 많은 제어권을 줍니다. 이것은 브라우저에서 비교하기 전에 양쪽을 정렬하는 것의
터미널 버전입니다.
구분자, 따옴표, 그리고 지저분한 현실
실제 CSV 파일은 끊임없이 규칙을 어깁니다. 쉼표를 포함하는 필드는 따옴표로 감싸야 하므로
"Lovelace, Ada"는 둘이 아니라 하나의 필드입니다. 따옴표로 감싼 필드 안의
따옴표는 두 번 씁니다: "She said ""hi""". 그리고 구분자 자체가 다양합니다.
쉼표를 소수점으로 쓰는 로케일의 스프레드시트는 세미콜론으로 내보내고,
탭으로 구분된 파일(TSV)은 데이터 파이프라인에서 흔합니다. 비교하기 전에
두 파일이 같은 구분자와 같은 따옴표 규칙을 쓰는지 확인하거나, RFC 4180을 따르는
파서로 정규화하세요. 그렇지 않으면 diff는 같은 데이터의 두 버전이 아니라
두 개의 다른 방언을 비교하는 것입니다.
주의해야 할 흔한 함정
| 함정 | 왜 문제가 되는가 | 해결 |
|---|---|---|
| 구분자 불일치 | 쉼표 vs 세미콜론이 모든 필드를 다르게 보이게 함 | 먼저 하나의 구분자로 정규화하세요 |
| 시작 부분의 BOM | 숨겨진 바이트 순서 표시가 첫 헤더 셀을 바꿈 | 비교 전에 BOM을 제거하세요 |
| 앞자리 0이 있는 ID | 스프레드시트가 007을 7로 바꿨을 수 있음 | ID 열을 텍스트로 유지하고 문자열로 비교하세요 |
| 포함된 줄바꿈 | 따옴표로 감싼 필드가 줄바꿈을 포함해 이후 모든 행을 밀어냄 | 줄 분할이 아니라 진짜 CSV 파서를 쓰세요 |
| 셀의 끝 공백 | 보이지 않는 공백이 변경으로 표시됨 | 비교 전에 셀 값을 잘라내세요 |
스프레드시트가 더 나은 도구일 때
텍스트 diff는 어떤 행이 바뀌었는지 찾고 변경을 데이터로 검토하는 데 완벽합니다. 하지만 수천 행에 걸쳐 필터링, 피벗, 또는 수식으로 비교해야 한다면 스프레드시트가 더 적합합니다. 두 파일을 가져오고, 키로 정렬하고, 룩업으로 불일치를 표시합니다. 두 접근법은 서로를 보완합니다. 빠른 시각적 읽기에는 diff를, 데이터를 잘게 나눠야 할 때는 스프레드시트를 사용하세요. 어느 쪽이든 기본 형식 규칙은 Wikipedia의 CSV 개요가 탄탄한 참고 자료입니다.
관련 도구
CSV가 다루는 유일한 형식인 경우는 드뭅니다. 같은 데이터가 JSON으로도 존재한다면, JSON 비교가 같은 아이디어를 적용합니다. 값 열의 중복 제거는 중복 줄 제거로 빠르게 할 수 있고, diff 전에 행을 예측 가능한 순서로 두는 것은 줄 정렬의 역할입니다.
자주 묻는 질문
- CSV 파일을 온라인으로 비교하면 어딘가에 업로드되나요?
- comparetext.org에서 diff는 브라우저에서 실행됩니다. 두 CSV 파일은 당신의 컴퓨터에서 JavaScript로 비교되므로, 저장 또는 공유를 명시적으로 클릭하지 않는 한 서버로 아무것도 전송되지 않습니다. 이는 고객 내보내기, 재무 데이터, 그리고 키 입력마다 업로드하는 사이트에 붙여넣고 싶지 않은 다른 스프레드시트에도 안전합니다.
- 왜 제 두 CSV 파일은 모든 행을 다르다고 표시하나요?
- 거의 항상 행 순서나 구분자 때문이지 실제 변경이 아닙니다. 한 내보내기가 다른 것과 다르게 정렬되었거나, 하나는 쉼표를 다른 하나는 세미콜론을 쓰거나, 줄 끝이 다릅니다. 두 파일이 같은 구분자를 쓰도록 한 다음, 둘 다 키 열로 정렬해 순서가 더 이상 문제 되지 않게 하세요. 그 후에는 diff가 보통 정말로 바뀐 소수의 행과 셀로 줄어듭니다.
- 행 순서를 무시하고 두 CSV 파일을 비교하려면 어떻게 하나요?
- 비교 전에 두 파일을 안정적인 키 열로 정렬하세요. 행에 ID가 있으면 그것으로 정렬하고, 없으면 전체 행을 정렬합니다. 헤더 줄은 그대로 두고 데이터 행만 정렬합니다. 브라우저에서는 정렬된 버전을 붙여넣을 수 있고, 명령줄에서는 헤더 다음의 파일을 정렬합니다. 두 파일이 같은 순서가 되면, 단순히 이동한 모든 행이 아니라 실제로 바뀐 행만 diff에 나타납니다.
- 왜 제 CSV는 쉼표 대신 세미콜론을 쓰나요?
- 많은 유럽 로케일은 쉼표를 소수점 구분자로 쓰기 때문에, 스프레드시트 앱은 모호함을 피하려고 대신 세미콜론 구분자로 CSV를 내보냅니다. 데이터는 같고 구분자만 다릅니다. 두 파일을 비교하기 전에 같은 구분자를 쓰는지 확인하세요. 그렇지 않으면 모든 필드가 변경으로 표시됩니다. CSV를 이해하는 도구로 둘 다 쉼표(또는 둘 다 세미콜론)로 정규화하면 해결됩니다. 탭으로 구분된 파일도 다른 구분자로 같은 문제를 가집니다.
- 열 순서가 다른 CSV 파일은 어떻게 비교하나요?
- 일반 텍스트 diff는 행을 왼쪽에서 오른쪽으로 비교하므로, 재정렬된 열은 데이터가 일치해도 완전한 변경처럼 보입니다. 이를 처리하려면, 먼저 두 파일에서 열이 일치하도록 재정렬하거나, 위치 대신 헤더 이름으로 비교하는 CSV 인식 도구를 쓰세요. csvkit 같은 명령줄 도구는 이름으로 열을 선택하고 재정렬할 수 있습니다. 열이 같은 순서로 정렬되면, 일반적인 행별 diff가 다시 작동합니다.
- 페이지가 멈추지 않고 큰 CSV 파일을 비교할 수 있나요?
- 예, 어느 정도까지는요. 줄 모드 diff는 각 문자가 아니라 먼저 전체 줄을 비교하므로 수천 행 파일에서도 빠르게 유지됩니다. 아주 큰 파일(수십 메가바이트 또는 수백만 행)은 데이터를 스트리밍하는 csvkit 같은 명령줄 도구나 데이터베이스 가져오기로 처리하는 것이 낫습니다. 브라우저에서 편안하게 스크롤할 수 있는 내보내기에는 온라인 diff가 더 빠른 선택입니다.
사용해 볼 준비가 되셨나요? CSV 비교 도구에 파일을 붙여넣고 무엇이 바뀌었는지 확인하세요.