Pythonでディレクトリ下のファイルを再帰的にリネームして通し番号を振る
pythonでディレクトリ(フォルダ)下のファイルを一括で変更して通し番号を振るスクリプトを作ったので備忘録を兼ねてまとめます。
Windowsでも動くような気はしますが、テストした環境はUbuntu 18.04 LTSです。
目標
以下のような構成のフォルダがあるとします。
$ tree dir1 dir1/ ├── a.txt └── b ├── b.txt ├── c │ └── c.txt └── d └── d.txt
これを以下のようにリネームするのが今回作りたかったスクリプトです。
$ python rename.py dir1 file $ tree dir1 dir1/ ├── b │ ├── c │ │ └── file_3.txt │ ├── d │ │ └── file_4.txt │ └── file_2.txt └── file_1.txt
要するに、ディレクトリの構造は変えずにファイルだけリネームし、与えられた接頭辞を付けて、通し番号を振りたかったんです。
スクリプト
完成したスクリプトは以下のとおりです。コメントで簡単な解説を入れました。最初は画像ファイルを対象とするつもりだったので変数名がそれに関連したものになってしまっていますが、ファイルの種類にかかわらず動作します。
ただ、globの再帰的なマッチを使用していますので、Python 3.5以降でないと正しく動作しません。
ファイル名の変更はファイルの上書き等によりデータのロストが起こりやすいものですので、お試しになる場合はバックアップを取るなどして自己責任でお願いします。
# rename.py import glob import os import sys indir = sys.argv[1] prefix = sys.argv[2] # ディレクトリ下のファイル名を再帰的に取得する path = os.path.join(indir, "**/*.*") all_imgs = glob.glob(path, recursive=True) all_imgs.sort() # ファイル数が何桁か調べる digit = len(str(len(all_imgs))) for index, img in enumerate(all_imgs, 1): # 元のディレクトリ構造とファイル名、拡張子を取得する ori_dir, ori_name = os.path.split(img) filename, suffix = os.path.splitext(ori_name) # 自分自身はリネームしない if ori_name == "rename.py": continue # 通し番号の桁を揃える num = str(index).zfill(digit) # 新しいファイル名の生成、ディレクトリと拡張子は元のまま new_name = "{0}_{1}{2}".format(prefix, num, suffix) new_path = os.path.join(ori_dir, new_name) # 変更後と同じ名前のファイルが存在する場合はスキップ if os.path.exists(new_path): sys.stderr.write( "{0} already exists\n".format(new_path)) continue # リネーム os.rename(img, new_path) print("{0} -> {1}".format(ori_name, new_name))