[자동화#3] CSV 파일 한 번에 합치기 (엑셀 자동 통합 루틴)

한줄 요약:
폴더에 흩어진 여러 CSV하나의 파일로 자동 합치기!
보고서/매출/로그 통합 작업을 파이썬으로 1번에 끝내자 🙌


1. 목표

  • 폴더 안의 *.csv헤더 중복 없이 위에서 아래로 합치기
  • 인코딩(UTF-8/CP949) 이 달라도 안전하게 처리
  • 결과를 combined.csv로 저장

2. 완성 코드 A (표준 라이브러리만 사용)

설치 없이 바로 실행 가능! (권장 시작 버전)

# CSV 파일 한 번에 합치기 (표준 라이브러리 버전)
import csv
import glob
import os

def merge_csv(input_folder, output_path, encoding_list=("utf-8-sig", "utf-8", "cp949"), delimiter=","):
    """
    input_folder : CSV들이 들어있는 폴더 경로
    output_path  : 결과 파일 경로 (예: combined.csv)
    encoding_list: 시도할 인코딩 우선순위
    delimiter    : 구분자 (기본 , / 세미콜론일 땐 ';')
    """
    csv_paths = sorted(glob.glob(os.path.join(input_folder, "*.csv")))
    if not csv_paths:
        print("⚠️ CSV 파일이 없습니다.")
        return

    wrote_header = False
    total_rows = 0
    with open(output_path, "w", newline="", encoding="utf-8-sig") as fout:
        writer = None

        for path in csv_paths:
            # 인코딩 자동 시도
            for enc in encoding_list:
                try:
                    with open(path, "r", newline="", encoding=enc, errors="strict") as fin:
                        reader = csv.reader(fin, delimiter=delimiter)
                        rows = list(reader)
                    # 성공했으면 루프 탈출
                    break
                except Exception:
                    rows = None
                    continue

            if rows is None or not rows:
                print(f"❌ 읽기 실패: {os.path.basename(path)}")
                continue

            header, body = rows[0], rows[1:]

            if writer is None:
                writer = csv.writer(fout, lineterminator="\n", delimiter=delimiter)

            # 첫 파일의 헤더만 기록
            if not wrote_header:
                writer.writerow(header)
                wrote_header = True

            # 본문 작성
            for row in body:
                writer.writerow(row)
            total_rows += len(body)
            print(f"✅ 합침: {os.path.basename(path)} ({len(body)}행)")

    print(f"\n🎉 완료! 총 {len(csv_paths)}개 파일, {total_rows}행 → {output_path}")

if __name__ == "__main__":
    folder = input("CSV 폴더 경로: ").strip()
    out    = input("결과 파일 경로(기본: combined.csv): ").strip() or "combined.csv"
    sep    = input("구분자(기본 , / 세미콜론 ; 입력 가능): ").strip() or ","
    merge_csv(folder, out, delimiter=sep)

특징

  • 추가 설치 없음
  • utf-8-sig → utf-8 → cp949 순으로 인코딩 자동 시도
  • 첫 파일의 헤더 1번만 유지

3. 완성 코드 B (pandas 고속 버전)

대용량/다양한 컬럼 처리에 더 편해요. 먼저 pip install pandas 필요!

# CSV 파일 한 번에 합치기 (pandas 버전)
import os
import glob
import pandas as pd

def read_any_csv(path):
    # 인코딩 후보 순회
    for enc in ("utf-8-sig", "utf-8", "cp949"):
        try:
            return pd.read_csv(path, encoding=enc)
        except Exception:
            continue
    raise ValueError(f"인코딩 감지 실패: {os.path.basename(path)}")

def merge_csv_pandas(input_folder, output_path):
    csv_paths = sorted(glob.glob(os.path.join(input_folder, "*.csv")))
    if not csv_paths:
        print("⚠️ CSV 파일이 없습니다.")
        return

    frames = []
    for p in csv_paths:
        try:
            df = read_any_csv(p)
            frames.append(df)
            print(f"✅ 읽음: {os.path.basename(p)} ({len(df)}행, {len(df.columns)}열)")
        except Exception as e:
            print(f"❌ 실패: {os.path.basename(p)} → {e}")

    if not frames:
        print("⚠️ 합칠 데이터가 없습니다.")
        return

    # 컬럼 자동 정렬/정합 필요 시 옵션
    # 공통 컬럼만 사용하려면: df_all = pd.concat(frames, join="inner", ignore_index=True)
    df_all = pd.concat(frames, join="outer", ignore_index=True)
    df_all.to_csv(output_path, index=False, encoding="utf-8-sig")
    print(f"\n🎉 완료! 총 {len(frames)}개 파일, {len(df_all)}행 → {output_path}")

if __name__ == "__main__":
    folder = input("CSV 폴더 경로: ").strip()
    out    = input("결과 파일 경로(기본: combined.csv): ").strip() or "combined.csv"
    merge_csv_pandas(folder, out)

특징

  • 헤더 자동 인식, 컬럼 불일치도 outer/inner 선택으로 처리
  • 저장은 UTF-8-SIG로 해서 엑셀에서 한글 깨짐 최소화

4. 팁 & 체크리스트

  • 구분자;(세미콜론)인 CSV도 많아요 → 코드의 delimiter=";"로 지정
  • 헤더가 없는 파일이 섞여 있으면 첫 줄이 데이터로 들어갈 수 있어요
    • pandas: pd.read_csv(path, header=None)로 조정
  • 중복 행 제거 # pandas 버전 후처리 예시 df_all.drop_duplicates(inplace=True)
  • 정렬 # '날짜' 컬럼 기준 오름차순 df_all.sort_values("날짜", inplace=True)

5. 예시 사용 시나리오

  • sales_2025_01.csv, sales_2025_02.csv, … 월별 매출 합치기
  • 로그 파일(일자별 CSV)을 분기/연별 하나로 통합
  • 설문 결과 여러 파일 병합 후 엑셀 피벗테이블 분석

6. 자주 하는 오류 & 해결

증상원인해결
한글 깨짐인코딩 불일치utf-8-sig 또는 cp949로 재시도
헤더가 두 번 생김각 파일마다 헤더 포함표준버전: 첫 파일만 헤더 기록, 나머진 본문만
열 개수가 서로 다름컬럼 불일치pandas 버전 사용, join="outer"/"inner" 선택
파일이 안 모임경로 오타/공백경로 따옴표, 절대경로 사용 권장

7. 연습문제

  1. ; 구분자 CSV 10개를 합쳐 report.csv로 저장해보세요.
  2. pandas 버전으로 합친 뒤, 중복 제거 + 날짜 정렬 후 저장해보세요.
  3. 파일명에 들어있는 월 정보(예: sales_2025_01.csv)를 컬럼으로 추가해보세요. import re m = re.search(r"(\d{4})_(\d{2})", os.path.basename(p)) if m: df["연"] = m.group(1) df["월"] = m.group(2)

이전 강좌 👈 [자동화#2] 폴더에서 특정 확장자만 모으기 (문서/사진 분류 자동화)
다음 강좌 👉 [에러#1] “pip가 안 돼요” 해결 체크리스트

댓글 남기기

광고 차단 알림

광고 클릭 제한을 초과하여 광고가 차단되었습니다.

단시간에 반복적인 광고 클릭은 시스템에 의해 감지되며, IP가 수집되어 사이트 관리자가 확인 가능합니다.