팀 업무·협업

팀 파일명 규칙을 정하고 Python으로 검사하기

간단한 팀 파일명 규칙을 정하고 합성 폴더에서 검사한 뒤, 어떤 파일도 이름을 바꾸거나 삭제하지 않고 검토용 보고서를 작성합니다. 검사기는 구조 오류, 잘못된 날짜, 허용되지 않은 확장자를 구분할 수 있습니다.

목차 보기

이런 분께 맞아요파일을 공유하거나 보관하기 전에 예측 가능한 파일명 규칙과 간단한 자동 검사를 적용하려는 팀을 위한 안내입니다.

준비할 것
  • Python 3.12와 해당 버전을 실행하는 터미널 명령이 준비되어 있어야 합니다.
  • 스크립트가 outputs 아래에 새 폴더를 만들 수 있는 작업 폴더가 필요합니다.
  • 팀에서 사용할 프로젝트 코드, 문서 이름, 버전 형식, 허용 확장자에 대한 합의가 필요합니다.
  • Python 표준 라이브러리인 csv, datetime, pathlib, re만 사용합니다.

01검사기를 만들기 전에 파일명 규칙부터 작성하기

이 예제에서는 YYYYMMDD_project_document_vNN.ext 형식을 사용합니다. 날짜는 숫자 8자리이며 실제 존재하는 달력 날짜여야 합니다. project와 document에는 소문자 영문자와 숫자를 사용하고 필요하면 하이픈으로 연결합니다. 버전은 v 다음에 정확히 숫자 2개를 사용합니다. 허용 확장자는 pdf, docx, xlsx, csv, txt입니다.

text
YYYYMMDD_project_document_vNN.ext

Example:
20260920_alpha_test-plan_v01.pdf
  • 파일에 해당하는 작업 날짜를 YYYYMMDD 형식으로 사용합니다.
  • project와 document 토큰에는 소문자만 사용합니다.
  • 파일명의 주요 네 부분 사이에만 밑줄을 사용합니다.
  • final, latest, new, revised 대신 v01, v02와 같은 버전 번호를 사용합니다.
  • 원래 파일 확장자를 유지하되 팀에서 합의한 허용 목록으로 제한합니다.

02정상 파일명과 오류 파일명이 섞인 합성 폴더 만들기

아래 파일명은 이 글을 위해 작성한 합성 데이터입니다. 준비용 스크립트를 create_file_naming_demo.py로 저장하세요. 빈 파일 8개를 만들며 그중 4개는 규칙을 따르고 4개는 의도적으로 규칙을 위반합니다.

python
from pathlib import Path

SOURCE = Path("outputs") / "file_naming_demo"
FILENAMES = [
    "20260920_alpha_test-plan_v01.pdf",
    "20260920_alpha_results_v02.csv",
    "20260921_beta_meeting-notes_v03.txt",
    "20261001_beta_budget_v01.xlsx",
    "2026-09-20_alpha_notes_v01.txt",
    "20260920_Alpha_notes_v01.txt",
    "20260920_alpha_notes_final.txt",
    "20260230_beta_results_v01.csv",
]

SOURCE.parent.mkdir(parents=True, exist_ok=True)
SOURCE.mkdir()  # Stop if the synthetic source already exists.

for filename in FILENAMES:
    target = SOURCE / filename
    with target.open("xb"):
        pass

처음 4개 파일명은 PASS가 예상됩니다. 다섯 번째는 YYYYMMDD 대신 하이픈이 들어간 날짜를 사용합니다. 여섯 번째는 project 토큰에 대문자가 있습니다. 일곱 번째는 vNN 대신 final을 사용합니다. 여덟 번째는 문자열 구조는 맞지만 2026-02-30이라는 존재하지 않는 날짜를 사용합니다.

03파일명 8개를 손으로 분류하기

파일명예상 상태이유
20260920_alpha_test-plan_v01.pdfPASS구조가 맞고 날짜도 유효함
20260920_alpha_results_v02.csvPASS구조가 맞고 날짜도 유효함
20260921_beta_meeting-notes_v03.txtPASS구조가 맞고 날짜도 유효함
20261001_beta_budget_v01.xlsxPASS구조가 맞고 날짜도 유효함
2026-09-20_alpha_notes_v01.txtFAILSTRUCTURE_ERROR
20260920_Alpha_notes_v01.txtFAILSTRUCTURE_ERROR
20260920_alpha_notes_final.txtFAILSTRUCTURE_ERROR
20260230_beta_results_v01.csvFAILINVALID_DATE

따라서 예상 결과는 검사 파일 8개, PASS 4개, FAIL 4개입니다. 실패 3개는 구조 문제이고, 1개는 구조는 맞지만 달력상 날짜가 잘못되었습니다.

04파일명을 변경하지 않고 검사하기

다음 스크립트를 check_file_names.py로 저장하세요. 파일명만 읽고 별도 출력 폴더에 CSV 보고서를 작성합니다. 원본 파일을 이름 변경, 이동, 수정, 삭제하지 않습니다.

python
import csv
import re
from datetime import datetime
from pathlib import Path

SOURCE = Path("outputs") / "file_naming_demo"
OUTPUT_DIR = Path("outputs") / "file_naming_result"
REPORT = OUTPUT_DIR / "file_naming_report.csv"
ALLOWED_EXTENSIONS = {"pdf", "docx", "xlsx", "csv", "txt"}

NAME_PATTERN = re.compile(
    r"^(?P<date>[0-9]{8})_"
    r"(?P<project>[a-z0-9]+(?:-[a-z0-9]+)*)_"
    r"(?P<document>[a-z0-9]+(?:-[a-z0-9]+)*)_"
    r"(?P<version>v[0-9]{2})\."
    r"(?P<extension>[a-z0-9]+)$"
)


def check_filename(filename: str) -> tuple[str, str]:
    match = NAME_PATTERN.fullmatch(filename)
    if match is None:
        return "FAIL", "STRUCTURE_ERROR"

    extension = match.group("extension")
    if extension not in ALLOWED_EXTENSIONS:
        return "FAIL", "UNSUPPORTED_EXTENSION"

    try:
        datetime.strptime(match.group("date"), "%Y%m%d")
    except ValueError:
        return "FAIL", "INVALID_DATE"

    return "PASS", ""


def main() -> None:
    if not SOURCE.is_dir():
        raise FileNotFoundError(f"Source folder not found: {SOURCE}")
    if OUTPUT_DIR.exists():
        raise FileExistsError(f"Output folder already exists: {OUTPUT_DIR}")

    files = sorted(path for path in SOURCE.iterdir() if path.is_file())
    results = []

    for path in files:
        status, issue = check_filename(path.name)
        results.append({
            "filename": path.name,
            "status": status,
            "issue": issue,
        })

    OUTPUT_DIR.parent.mkdir(parents=True, exist_ok=True)
    OUTPUT_DIR.mkdir()
    with REPORT.open("x", encoding="utf-8", newline="") as stream:
        writer = csv.DictWriter(
            stream,
            fieldnames=["filename", "status", "issue"],
        )
        writer.writeheader()
        writer.writerows(results)

    passed = sum(row["status"] == "PASS" for row in results)
    failed = len(results) - passed
    print(f"Files checked: {len(results)}.")
    print(f"Passed: {passed}; failed: {failed}.")
    print(f"Report: {REPORT.as_posix()}")


if __name__ == "__main__":
    main()
text
python check_file_names.py

05예상 보고서와 비교하기

보고서에는 원본 파일마다 한 행씩 있어야 합니다. 검사 전에 파일명을 알파벳순으로 정렬하므로 출력 순서는 준비용 스크립트 목록이 아니라 정렬된 파일명 순서를 따릅니다.

예상 항목
검사 파일8
PASS4
FAIL4
STRUCTURE_ERROR3
INVALID_DATE1

아래 예상 콘솔 출력은 합성 파일명과 검사기를 바탕으로 손으로 도출한 결과이며 실제 실행 로그가 아닙니다.

text
Files checked: 8.
Passed: 4; failed: 4.
Report: outputs/file_naming_result/file_naming_report.csv

06파일명을 바꾸기 전에 실패 항목 검토하기

  • 정상으로 의도한 네 파일명이 모두 PASS인지 확인합니다.
  • 20260230_beta_results_v01.csv가 정규식 구조에는 맞아도 잘못된 날짜로 거부되는지 확인합니다.
  • 공유 파일의 이름을 누가 변경할 수 있는지 먼저 정한 뒤 수정합니다.
  • 기존 파일명을 참조하는 링크, 스크립트, CAD 참조, 문서 링크, 공유 드라이브 바로가기가 있는지 확인합니다.
  • OUTPUT_DIR을 바꾸지 않고 다시 실행합니다. 이전 보고서를 교체하지 않고 FileExistsError로 중단되어야 합니다.
문제확인할 사항
STRUCTURE_ERROR가 너무 많음문서화한 팀 규칙이 사람들이 실제로 사용하는 방식과 맞는지 확인하세요.
대문자나 공백이 자주 나타남파일마다 임의로 수정하지 말고 금지할지 허용할지 규칙을 명확하게 결정하세요.
형식은 정상인 날짜가 실패함YYYYMMDD 문자열이 실제 달력 날짜인지 확인하세요.
final이나 latest가 반복적으로 사용됨명시적인 버전 번호를 사용하고 승인 또는 배포 상태는 별도 규칙으로 정의하세요.
이름 변경 후 참조가 깨짐종속 시스템과 링크를 평가하기 전에는 자동 이름 변경을 적용하지 마세요.

07파일명 규칙을 지나치게 복잡하게 만들지 않기

파일명 규칙은 버전 관리 시스템, 문서 관리 시스템, 메타데이터를 대신할 수 없습니다. 파일명이 v03이라고 해서 실제 내용이 v02보다 최신이거나, 올바른 사람이 승인했거나, 올바른 프로젝트에 연결되었다는 뜻은 아닙니다.

이 예제는 한 폴더 바로 아래의 파일만 검사합니다. 하위 폴더를 재귀적으로 검사하지 않고, 여러 공유 드라이브 전체에서 이름의 고유성을 확인하지 않으며, 파일 내용이나 project 토큰이 실제 프로젝트와 일치하는지도 검증하지 않습니다.

팀 규칙을 변경할 때는 적용 시작일을 기록하고 기존 파일을 그대로 인정할지 새 규칙으로 변경할지 결정하세요. 실용적인 규칙은 사람들이 기억할 수 있을 정도로 단순하면서도 자동 검사가 의미 있는 결과를 낼 정도로 명확해야 합니다.

실행·검증 기록

2026-09-20 · 예제 수동 검토 · 대상: Python 3.12 · 표준 라이브러리: csv, datetime, pathlib, re · 실행하지 않음

  • 합성 파일명 8개를 PASS 4개, FAIL 4개로 수동 분류했습니다.
  • 하이픈 날짜, 대문자 project 토큰, final 버전 표기 등 구조 실패 3개를 확인했습니다.
  • 20260230이 숫자 8자리 형식에는 맞지만 달력상 2026-02-30은 존재하지 않음을 확인했습니다.
  • 예상 결과를 PASS 4, FAIL 4, STRUCTURE_ERROR 3, INVALID_DATE 1로 수동 계산했습니다.
  • 파일명 전체 일치 검사, 허용 확장자 검사, 실제 날짜 검증, 출력 충돌 방지, 이름 변경이나 삭제 작업이 없음을 코드로 검토했습니다.
  • 예상 콘솔 출력을 손으로 도출했습니다.
검증 한계
  • 이 응답의 작성자는 코드를 실행하지 않았으며, 파일이나 보고서를 실제로 만들지 않았습니다.
  • 재귀 폴더, 공유 드라이브 링크, 대소문자를 구분하지 않는 파일시스템 동작, 프로젝트 간 고유성, 응용 프로그램 종속 참조는 시험하지 않았습니다.
  • 파일명 규칙은 예시 팀 정책이며 실제 업무 방식에 맞게 수정해야 합니다.
  • 공식 문서 URL은 알려진 문서 위치를 사용했지만 실시간으로 접속해 확인하지 않았습니다.

사이트 전체 작성·검증 원칙

참고 출처

설명과 예제는 직접 작성했습니다. 관련 동작과 개념은 아래 공식 자료에서 확인할 수 있습니다.