MENU

[Python] 複数ファイルを一カ所に一括移動/コピー、または一括削除する。

本記事で紹介するスクリプトによるファイル移動・削除で生じた問題について、筆者は一切の責任を負いません。

目次

1. 結論:Pythonスクリプトを実装しました。

PC上に散在している複数のファイルを、指定したフォルダ直下に集約する形で移動させるPythonスクリプトmove_target_files_into_a_folder.pyを実装しました。具体的なイメージは、以下の通りです。

  • 元のファイル群のパス
    1. /photos/family/birthday.jpg(file1.txtに記載)
    2. /images/pets/dog.png(file2.txtに記載)
  • 移動後のファイル群のパス
    1. /target_folder/file1.txt/photos@family@birthday.jpg
    2. /target_folder/file2.txt/images@pets@dog.png

元のファイル群がPC上の異なるフォルダに格納されていても、本スクリプトにより、任意のフォルダ(上の例では/target_folder)配下に集約することができます。本スクリプトには、移動対象の絶対ファイルパスを1行ずつ列挙したTXTファイルを複数入力することができ(上記例のfile1.txtおよびfile2.txt)、そのTXTファイル名は移動先のフォルダ配下のサブフォルダ名として残ります。

また、移動後のファイル名が、元の絶対ファイルパスを特定文字で結合した文字列となることで、万が一移動後に元に戻したい(UNDOしたい)場合でも、移動後のファイル名を参照することで切り戻すことができます。この切り戻しを実行するPythonスクリプトundo_move_target_files_into_a_folder.pyも同時に実装しています。

2つのスクリプトは、以下のGitリポジトリにまとめています。実行方法はリポジトリのREADME-ja.mdを参照してください。

設定ファイルへのオプション指定により、元のファイルを残したまま、移動ではなく「コピー」させることも可能です。また、移動後のフォルダを削除することで、対象ファイルを最終確認しながら一括削除する、という使い方も可能です。

2. 実装解説

2.1. クラス「MoveFileAsAbsolutePathJoinedNameConfig」

移動のために必要な以下の処理を、ファイルごとにワンストップで管理するためのクラスMoveFileAsAbsolutePathJoinedNameConfigを実装しています。特に、全ての検証をこのクラスのコンストラクタに含めているため、移動不可のファイルのインスタンスはスクリプト上で存在できないようになっています。これにより、移動に必要な処理が分散してしまうことを防止し、保守性を高めつつ、「移動」という不可逆操作を可能な限り安全に処理できるように工夫しています。

  • ファイルの読み取り権限の検証
  • ファイルの親フォルダの書き込み権限の検証(移動に必要)
  • 移動先のフォルダの存在と書き込み権限の検証
  • 結合文字の検証
  • 移動後のファイルパスの組み立て
  • 移動後のファイルパスの長さの検証
  • ファイルの移動の実行(検証が全て完了してからのみ)

2.2. 不可逆操作の安全性確保

「移動」という不可逆操作を可能な限り安全に処理できるように、以下の4つの点でも工夫しています。

(1) 全ファイルが移動可能であることを検証できた場合にのみ移動を実行

前項のクラスMoveFileAsAbsolutePathJoinedNameConfigのインスタンスを、まず全てのファイルについて生成し、全てのファイルが移動可能であることを保証できる状態になってから、実際に移動を実行する実装にしています。インスタンス生成時に発生した例外はExceptionGroupとして取りまとめ、例外が1ファイルでも存在する場合は、エラー内容を全て出力して処理を中止します。

(2) 実行直前の最終確認

全ファイルの検証が完了したあとに最終確認として、ユーザがyesと標準入力をする必要があり、移動を実行する直前にキャンセルすることも可能です。

2025-11-09 22:16:28,823 [INFO] __main__:   1 files on the file "./data/file1.txt".
2025-11-09 22:16:28,823 [INFO] __main__:   1 files on the file "./data/file2.txt".
2025-11-09 22:16:28,824 [INFO] __main__:   2 files in total.
Are you sure to MOVE the files? ("yes" or others): yes

(3) 移動のログ出力

ファイルの移動時に、移動前後のパスをログファイルに書き込む仕様になっているので、全ての移動の詳細をあとで確認することができます。

move_from,move_to
/photos/family/birthday.jpg,/target_folder/file1.txt/photos@family@birthday.jpg
/images/pets/dog.png,/target_folder/file2.txt/images@pets@dog.png

(4) 切り戻しスクリプトの実装

処理完了後に戻したくなった場合でも、スクリプトundo_move_target_files_into_a_folder.pyを利用することで、全てのファイルを元に戻すことができます。何らかの理由で移動中に処理が中断されてしまった場合でも、中途半端に移動されたファイルを同様に戻すことができるので、不可逆な状態が極力存在し得ないような構造になっています。

筆者

本記事は以上です。ここまで読んでいただき、ありがとうございました!

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!

筆者

ユーマン
在籍: SIer企業
職務: Python歴8年の開発職
大学: ロボ設計/PV制作 @NHKロボコン優勝サークル
大学院: 学会発表にて2度優秀賞 @AI研究
目標: "ふと思いついたモノを何でもつくれちゃう人"になりたい!
好き: Python / Excel / 友人たちとの交流 / カフェ作業 / アフター5の自分時間 / 自己分析 / ホラー映画 / '00年代アニメ / 散歩や登山 / スキー / Mr.Children / 笑顔がステキな人
目次