スクリプト・ファイル自動化

フォルダー内のファイル一覧をCSVで作成する

サブフォルダーを走査し、ファイルパス、拡張子、サイズ、更新日時を表として記録します。元のファイルと既存の結果をそのまま保持したまま、まず4つの小さなサンプルファイルで確認します。

目次を表示

この翻訳はAIで作成しました。コード、単位、数値は原文と併せて確認してください。各言語のネイティブ話者による校閲は、まだ完了していません。 English

対象読者フォルダー内の文書数や保存場所を手作業で一覧化してきたPython初心者

準備するもの
  • Python 3.12以降をインストールし、ターミナルで python --version を実行してバージョンを確認します。
  • サンプルZIPを新しいフォルダーに展開します。ZIPアーカイブ内からサンプルを実行しないでください。
  • example.py があるフォルダーでターミナルを開きます。Windowsで python コマンドが使えない場合は py を使用します。macOSまたはLinuxでは、環境によって必要であれば python3 を使用します。
  • 外部パッケージやアカウントは必要ありません。同梱ファイルは、このチュートリアル用に作成された合成データです。

014つのファイルで最初の一覧を作成する

出力フォルダーを作成しただけでは、この作業が完了したとはいえません。CSVには4つの元ファイルがそれぞれ正確に1回ずつ含まれ、一覧に記録されたサイズの合計が63バイトであり、元の内容が変更されていない必要があります。自分の作業フォルダーに進む前に、同梱データでこれらの条件を確認してください。

  1. 展開したフォルダー内で example.py、README.txt、sample_files フォルダーを探します。
  2. sample_files を開き、readme.txt、empty.txt、および docs と reports のサブフォルダーを確認します。empty.txt は意図的に空です。
  3. 以下のコマンドをターミナルで1回実行します。実行中は入力ファイルを移動したり編集したりしないでください。
  4. 完了メッセージと出力パスが表示されたら、outputs/file_list.csv を開きます。
bash
python example.py

02パスと列の意味を理解する

コードは現在のターミナルフォルダーではなく、example.py の場所を基準に開始します。BASE 配下の sample_files だけを走査するため、内部の配置を変えなければサンプルフォルダー全体を移動できます。outputs は走査対象フォルダーの外にあるため、後で再実行しても結果CSVが入力一覧に含まれません。

列意味確認する点
relative_pathsample_files からの相対パス同じ名前のファイルでも、別のフォルダーにあれば区別できます。
extension最後の拡張子を小文字で表示拡張子がない場合は (없음) と表示され、tar.gz は .gz と表示されます。
size_bytes整数のバイト数で表したファイルサイズ0は欠損値ではなく、空のファイルを意味します。
modified_utcUTCでのファイル更新日時末尾の +00:00 はUTCを意味し、韓国の現地時刻とは異なります。

relative_path は、OSをまたいで読みやすくするためにスラッシュを使用します。結果はこのパスで並べ替えられます。内部のファイル走査順序には依存しないため、同じ入力に対する行順を比較しやすくなります。

03この例で使用する完全なコード

collect_files はファイル情報を収集し、main は新しいCSVを書き出します。入力の確認が完了するまで outputs は作成されません。読み取れないフォルダーやリンクに遭遇した場合は、不完全な一覧を正常な結果として保存せずに停止します。

example.py
"""sample_files를 읽어 outputs/file_list.csv에 목록을 기록합니다. 원본은 변경하지 않습니다."""

import csv
import os
import sys
from datetime import datetime, timezone
from pathlib import Path

BASE = Path(__file__).resolve().parent
INPUT = BASE / "sample_files"
OUTPUT = BASE / "outputs"
FIELDS = ["relative_path", "extension", "size_bytes", "modified_utc"]


def is_link(path):
    # Windows 연결 디렉터리(junction)도 Python 3.12 이상에서는 거부합니다.
    return path.is_symlink() or getattr(path, "is_junction", lambda: False)()


def collect_files(folder):
    if is_link(folder) or not folder.is_dir():
        raise ValueError("sample_files는 실제 폴더여야 합니다.")
    rows = []

    def stop_on_error(error):
        raise error

    # 하위 폴더까지 읽되, 링크를 따라 다른 폴더로 나가지 않습니다.
    for root, dirs, files in os.walk(folder, followlinks=False, onerror=stop_on_error):
        root = Path(root)
        for name in dirs + files:
            if is_link(root / name):
                raise ValueError(f"링크는 처리하지 않습니다: {root / name}")
        for name in sorted(files):
            path = root / name
            if not path.is_file():
                raise ValueError(f"일반 파일이 아닙니다: {path}")
            stat = path.stat()
            rows.append({
                "relative_path": path.relative_to(folder).as_posix(),
                "extension": path.suffix.lower() or "(없음)",
                "size_bytes": stat.st_size,
                "modified_utc": datetime.fromtimestamp(
                    stat.st_mtime, timezone.utc
                ).isoformat(timespec="seconds"),
            })
    return sorted(rows, key=lambda row: row["relative_path"])


def main():
    if OUTPUT.exists() or OUTPUT.is_symlink():
        raise FileExistsError("outputs가 이미 있습니다. 기존 결과를 옮긴 뒤 실행하세요.")
    rows = collect_files(INPUT)  # 모두 읽은 뒤에만 출력 폴더를 만듭니다.
    OUTPUT.mkdir()
    target = OUTPUT / "file_list.csv"
    # x는 기존 파일을 덮어쓰지 않는 모드입니다. BOM은 한글 CSV 열기에 도움을 줍니다.
    with target.open("x", encoding="utf-8-sig", newline="") as stream:
        writer = csv.DictWriter(stream, fieldnames=FIELDS)
        writer.writeheader()
        writer.writerows(rows)
    print(f"완료: {len(rows)}개 파일, 합계 {sum(row['size_bytes'] for row in rows)}바이트")
    print(target)
    return 0


if __name__ == "__main__":
    try:
        raise SystemExit(main())
    except (OSError, ValueError) as error:
        print(f"중지: {error}", file=sys.stderr)
        raise SystemExit(2)

csv.DictWriter がCSVの区切り文字と引用符処理を行います。ファイルは newline を空文字列に設定し、UTF-8 BOM付きで保存されます。出力ファイルは x モードで開かれるため、すでに存在するファイルを上書きしません。この例では、まず outputs フォルダー自体が存在するかどうかを確認します。

044行と合計サイズを確認する

relative_pathextensionsize_bytes
docs/agenda.txt.txt15
empty.txt.txt0
readme.txt.txt17
reports/sales.csv.csv31

表の合計は 15 + 0 + 17 + 31 = 63 バイトです。ターミナルにも “완료: 4개 파일, 합계 63바이트”(完了: 4ファイル、合計63バイト)と表示されます。CSVの1行目には列名が入るため、表計算ソフトではヘッダーを含めて5行表示されます。empty.txt を数え忘れないでください。

05一覧だけでなく元ファイルも確認する

  1. CSV内の4つのパスを、それぞれ sample_files 内の実際の場所と照合します。docs と reports フォルダー自体はデータ行には含まれません。
  2. 空ファイルがサイズ0バイトで含まれていること、および拡張子が .txt と .csv であることを確認します。
  3. sample_files/readme.txt を開き、元のテキスト Sample inventory がそのまま残っていることを確認します。
  4. 同じコマンドをもう一度実行します。“outputs가 이미 있습니다”(outputs はすでに存在します)で停止し、最初の結果がそのまま保持されることを確認します。

失敗条件も設計の一部です。再実行を妨げるからといって、出力保護コードを削除しないでください。以前の結果を残すには、再実行前に outputs を日付を含む名前へ変更するか、ZIPを新しいフォルダーに展開して新しいテストを開始します。

06自分のフォルダーに適用する

最初から作業フォルダー全体をこの例の対象にしないでください。sample_files のコピーに、代表的なファイルを数個入れて試します。Path オブジェクトは、韓国語文字や空白を含むファイル名も扱えます。別の場所を指すシンボリックリンクやディレクトリジャンクションは対応範囲外なので、通常のファイルだけを含む小さなコピーを使用してください。

  1. 既存のサンプル入力と結果はそのまま残し、新しい練習用フォルダーを作成します。
  2. 手作業で数えられるよう、sample_files に5~10個のファイルを配置します。1階層分のサブフォルダーも含めます。
  3. 一覧を生成し、相対パスが想定した場所を指していることを確認します。
  4. 確認済みのルールを変えずに、ファイル数を増やします。ファイルサイズは内容の文字数と異なる場合があるため、単位はバイトのままにします。

入力フォルダーが空の場合、スクリプトはヘッダーだけのCSVを作成し、ファイル数0と報告します。これはフォルダー自体が存在せず停止する場合とは異なります。空のフォルダーも有効な作業状態になり得るため、結果を解釈するときは両者を区別してください。

07よくあるエラーを解決する

症状考えられる原因次にすること
python command not foundPythonランチャーのインストールまたはPATH設定の問題まず python --version を確認し、Windowsでは py も試します。
sample_files must be a real folderフォルダーが存在しない、またはリンクが使用されているZIP全体を展開したことを確認し、実体のあるフォルダーを復元します。
outputs already exists以前の実行結果がまだ残っている既存の結果を安全な場所へ移動してから再実行します。
Korean text appears garbledファイルを開くプログラムが文字エンコーディングを誤って解釈しているCSVをインポートするときにUTF-8を選択し、元ファイルは変更しないでください。
Read permission errorアクセスできないフォルダーまたはロックされたパスまずアクセス可能な練習用コピーに対象を絞ります。

08この一覧から分かることと分からないこと

結果には実行時に観測されたファイル情報が含まれます。これは重複内容の検査でも、復元可能なバックアップでもありません。同じファイルサイズでも、2つの文書の内容が異なることがあります。ハッシュ比較が必要な場合は、別の作業として定義し、必要な列を追加してください。

この初心者向けの例では、走査中に別のプログラムが名前や内容を変更する場合、ネットワークドライブの遅延、非常に多数のファイルをメモリに収集する場合は扱っていません。ディスク書き込みに失敗すると不完全な outputs フォルダーが残ることがあるため、完了メッセージと結果行数の両方を確認してください。

実行・検証の記録

2026-09-19 · Windows 11 · CPython 3.12.14 · 追加パッケージなし · 配布物の一時コピーで実行

  • 入れ子フォルダー内のファイルを含む4ファイル、合計63バイトであることを確認
  • 空の入力フォルダーではヘッダーのみのCSVが生成されることを確認
  • 入力フォルダーが存在しない場合、および outputs フォルダーがすでに存在する場合に拒否されることを確認
  • 別のフォルダーから実行し、作業ディレクトリに依存しないことを確認
  • 実行前後で入力ファイルのSHA-256ハッシュが同一であることを確認
検証範囲の限界
  • macOSまたはLinuxでは実行していません。
  • 更新日時は展開後に変わる場合があります。
  • 同時ファイル変更とディスク容量不足はテストしていません。

サイト全体の執筆・検証方針

自分で実行するためのサンプルファイル

コード、入力データ、実行手順が含まれています。展開して、まずREADME.txtを読んでください。

サンプルZIPをダウンロード

サンプルコード、ファイル名、入力キーは原文のままです。翻訳本文のコマンドと確認手順も併せて参照してください。

独自に作成した練習用資料 · 元のファイルを別に保管してから実行してください。

参考資料

説明と例は独自に作成しました。関連する動作や概念は、以下の公式資料で確認できます。