Open1

フォルダ内のtxtファイルを特定比率で分割コピー(Python)

MugichaMugicha
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
フォルダ内の .txt ファイルを指定した比率で二つのフォルダに分割コピーするスクリプト。

実行例:
    python split_txt_files.py \
        /path/to/src_dir \
        /path/to/dst_dir_80 \
        /path/to/dst_dir_20 \
        --ratio 0.8 \
        --seed 42

    例: src_dir にあるテキストファイルの 80% を dst_dir_80 に、20% を dst_dir_20 にコピーします。
"""

import os
import shutil
import random
import argparse


def split_txt_files(src_dir, dst_dir_a, dst_dir_b, ratio=0.8, seed=None):
    """
    指定したsrc_dir内の .txt ファイルを、与えられた比率(例: 0.8 は80%/20%)で
    dst_dir_a と dst_dir_b の二つのディレクトリに分割コピーする関数。

    パラメータ:
      src_dir (str): .txt ファイルが格納されたソースディレクトリ
      dst_dir_a (str): 第一グループ(例: 80%)のコピー先ディレクトリ
      dst_dir_b (str): 第二グループ(例: 20%)のコピー先ディレクトリ
      ratio (float): 分割比率(デフォルト: 0.8 は80%%/20%%)
      seed (int, optional): 再現性のための乱数シード
    """
    # 元ディレクトリが存在するか確認
    if not os.path.isdir(src_dir):
        raise NotADirectoryError(f"ソースディレクトリ '{src_dir}' が存在しません")

    # コピー先ディレクトリを作成(存在しない場合)
    os.makedirs(dst_dir_a, exist_ok=True)
    os.makedirs(dst_dir_b, exist_ok=True)

    # src_dir内の .txt ファイル一覧を取得
    txt_files = [f for f in os.listdir(src_dir) if f.lower().endswith(".txt")]
    if not txt_files:
        print("ソースディレクトリに .txt ファイルが見つかりませんでした。")
        return

    # 乱数シードを設定(再現性のため)
    if seed is not None:
        random.seed(seed)

    # ランダムにシャッフルして分割
    random.shuffle(txt_files)

    # 分割位置を算出
    split_index = int(len(txt_files) * ratio)

    # 80% と 20% に分割
    group_a = txt_files[:split_index]
    group_b = txt_files[split_index:]

    # 各ディレクトリへコピー
    for fname in group_a:
        shutil.copy2(os.path.join(src_dir, fname), os.path.join(dst_dir_a, fname))
    for fname in group_b:
        shutil.copy2(os.path.join(src_dir, fname), os.path.join(dst_dir_b, fname))

    # 結果を表示
    print(f"合計ファイル数: {len(txt_files)} 件")
    print(f"{len(group_a)} 件を '{dst_dir_a}' にコピーしました")
    print(f"{len(group_b)} 件を '{dst_dir_b}' にコピーしました")


if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description="フォルダ内の .txt ファイルを指定した比率で二つのフォルダに分割コピーします。"
    )
    parser.add_argument("src_dir", help=".txt ファイルが格納されたソースディレクトリ")
    parser.add_argument(
        "dst_dir_a", help="第一グループ(例: 80%)のコピー先ディレクトリ"
    )
    parser.add_argument(
        "dst_dir_b", help="第二グループ(例: 20%)のコピー先ディレクトリ"
    )
    parser.add_argument(
        "--ratio",
        type=float,
        default=0.8,
        help="分割比率(デフォルト: 0.8 は80%%/20%%)",
    )
    parser.add_argument(
        "--seed", type=int, default=None, help="オプション: 再現性のための乱数シード"
    )
    args = parser.parse_args()

    split_txt_files(args.src_dir, args.dst_dir_a, args.dst_dir_b, args.ratio, args.seed)