본문 바로가기
카테고리 없음

CSV 다루기

by 경자꿈사 2025. 2. 28.

프로그램을 개발하다 보면 어떤 데이터들은 장기적으로 보관할 수 있는 저장소에 저장해야 할 필요가 있다.
그러한 저장소로써 가장 일반적으로 사용되는 것이 파일 시스템과 데이터베이스이다.
그중 파일 시스템과 관련해서는 이미 '도서 관리 프로그램'을 통해서 파일에 도서 관련 데이터를 저장하고 다시 파일로부터 데이터를 읽어오는 코드를 작성해 보았다.
그런데, 도서 관리 프로그램에서는 프로그램 고유의 규칙을 정해서 파일에 데이터를 저장했었지만, 이미 컴퓨터 프로그래밍 분야에서 널리 사용되는 CSV, JSON, YAML 등의 포맷 규칙이 있다.

이번 글에서는 CSV를 살펴보려고 한다.
CSV는 'Comma-Separated Values'의 약자로서 말 그대로 값들을 콤마(,)로 구분하여 파일에 저장하는 포맷이다.

아래 그림은 CSV 클래스의 generate 메서드를 사용하여 2차원 배열의 데이터를 CSV 포맷의 문자열로 변환한 후 test.csv 파일에 작성하는 간단한 예제이다.
generate 메서드가 블록 파라미터를 통해 전달해 주는 CSV 객체의 << 연산자 메서드를 사용하여 배열에 담긴 데이터를 CSV 포맷으로 변환할 수 있다.
generate 메서드가 반환한 결괏값(csv_data)을 보면 2차원 배열의 안쪽 배열의 요소들은 콤마로 연결되어 있고, 그렇게 연결된 문자열들은 다시 개행 문자("\n")로 연결된 것을 볼 수 있다.

실제 생성된 test1.csv 파일을 파일 편집기로 열어 보면 아래 그림처럼 콤마가 포함된 텍스트 두 줄이 보이고, 
test1.csv 파일을 더블 클릭하여 엑셀 프로그램으로 열어 보면 두 개의 열을 갖는 데이터 두 개(행)가 잘 보인다.

그런데 데이터를 CSV 포맷으로 파일에 바로 저장하고 싶다면 다음처럼 CSV 클래스의 open 클래스 메서드를 사용하면 된다.

만약 CSV 포맷으로 저장해야 할 데이터 안에 콤마가 포함된 값이 들어 있다면 어떻게 될까?
다음 그림처럼 값에 콤마를 넣고 테스트를 바로 해보자.

생성된 test3.csv 파일을 파일 편집기로 열어 보면 콤마가 포함된 값이 쌍따옴표로 묶여 있는 게 보이고, test3.csv 파일을 엑셀로 열어 보면 여전히 '2열 x 2행' 형태로 잘 나오는 것을 볼 수 있다.
즉, csv 라이브러리에서 알아서 잘 처리해 주니 걱정할 필요가 없다.

아래 그림을 보면 csv 라이브러리에서 사용하는 기본 옵션 값들을 볼 수 있다.
값들을 구분하는 문자로 사용하는 구분자(:col_sep)는 콤마(",")로 되어 있고, 값에 구분자가 포함되어 있을 경우 해당 값을 단일 값으로 표현하기 위해 사용하는 인용 문자(:quote_char)는 쌍따옴표("\"")인 것을 볼 수 있다.

아래 그림처럼 구분자를 "^"로 하여 CSV 포맷으로 변환하면 콤마가 포함된 값이 인용 문자로 감싸이지 않는 걸 볼 수 있다.
그리고 값에 "^"을 포함시키고 다시 구분자를 "^"로 하여 CSV 포맷으로 변환하면 이번에는 "^"가 포함된 값이 인용 문자로 감싸인다.

이번에는 프로그램에서 CSV 포맷으로 저장된 파일을 읽어와 보자.
아래 그림처럼 foreach 클래스 메서드를 사용하면 특정 csv 파일을 라인 단위로 읽어와 배열로 변환해서 블록 파라미터로 전달해 준다.

그런데 CSV 형식으로 파일에 데이터를 저장할 때 값을 설명하는 헤더 정보를 함께 저장하기도 하는데, 이렇게 헤더 정보가 포함된 csv 파일을 읽어와 처리할 때는 배열이 아닌 해시로 데이터를 다룰 수도 있다.
다음 그림처럼 foreach 메서드를 호출할 때 headers 옵션 값을 true로 주면 블록 파라미터로 배열이 아닌 CSV::Row 클래스의 객체를 전달해 주는데, to_h 메서드를 호출하면 헤더를 키로 하는 해시를 돌려준다.
참고로 CSV::Row 클래스는 Enumerable 모듈을 인클루드 하고 있다.

아래는 헤더 명을 한글로 작성해 보았는데, 생성된 test5.csv 파일을 파일 편집기로 열어 보면 한글 헤더명이 잘 보이지만 엑셀로 열어 보면 한글이 깨져 보인다.

위의 예제에서 test5.csv 파일이 기본 인코딩인 UTF-8을 사용하여 작성이 됐는데, 윈도우의 엑셀에서 csv 파일 내용을 시스템의 기본 인코딩(보통 CP949)으로 해석하기 때문이다.
cmd 창을 열어 chcp 명령을 실행하면 현재 윈도우 시스템의 기본 인코딩 정보를 확인할 수 있다.

위의 예제를 아래 그림처럼 encoding 옵션을 "cp949"로 주고 다시 실행해 보자.

생성된 test6.csv 파일을 엑셀로 열어 보면 한글 헤더명이 깨지지 않고 잘 나오는 것을 확인할 수 있다.

 

See you again~