한줄 요약:
폴더에 흩어진 여러 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:
- 중복 행 제거
# 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. 연습문제
;구분자 CSV 10개를 합쳐report.csv로 저장해보세요.- pandas 버전으로 합친 뒤, 중복 제거 + 날짜 정렬 후 저장해보세요.
- 파일명에 들어있는 월 정보(예:
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가 안 돼요” 해결 체크리스트