8
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Python】大量ファイルを一括リネーム

Last updated at Posted at 2023-05-27

Introduction

頻繁にデータセットに大量のファイルを追加することがあり、ファイル名に統一感がなくないことが気になっていました。

使用する端末が異なることもあり、何かある度に使い捨てでコードを書くのが手間なため備忘録とします。

ファイル名が被るとリネームする手間が増えるのと、雑多なデータセットを見る際の抵抗感を減らすことが目的です。

処理自体は単純ですが他の記事を見ていると、バックアップせずに使って上書かれ、泣きを見そうなスクリプトが多いです。
コピペしても比較的安全に使用できるコードを紹介します。

本記事が少しでも読者様の学びに繋がれば幸いです!
「いいね」をしていただけると今後の励みになるので、是非お願いします!

環境

Ubuntu22.04
Python3.11.1

実装

先にソースコード全体を紹介します。

rename.py
import os
import argparse
from glob import glob
import shutil

parser = argparse.ArgumentParser()
parser.add_argument("-i", "--input", type=str, default="input")
parser.add_argument("-o", "--output", type=str, default="output")
parser.add_argument("-n", "--name", type=str, required=True)
parser.add_argument("-e", "--extension", type=str, required=True)
args = parser.parse_args()

input_dir = args.input
output_dir = args.output
backup_dir = "backup"

os.makedirs(output_dir, exist_ok=True)
os.makedirs(backup_dir, exist_ok=True)

files = glob(f"{input_dir}/*")

for i, file in enumerate(files):
    rename_file = f"{output_dir}/{args.name}_{i}.{args.extension}"
    backup_file = f"{backup_dir}/{os.path.basename(file)}"
    while os.path.exists(rename_file):
        i += 1
        rename_file = f"{output_dir}/{args.name}_{i}.{args.extension}"
    shutil.copy2(file, backup_file)
    shutil.move(file, rename_file)
  1. ./input(又は-iで指定するディレクトリ)にファイルを格納。
  2. コピペして以下のコマンドを実行。
    python3 rename.py -n <ファイル名> -e <拡張子>
    
  3. ./backupにリネーム前のファイル、./outputにリネーム後のファイルが格納されていることを確認。

お試し

./inputに画像を格納します。
フェアリーペンギンのデータセットを作る予定で追加を重ねた結果、統一感のないネーミングになってしまいました。(という設定です)

Screenshot from 2023-05-27 12-15-16.png

リネームのスクリプトを実行します。
ファイル名はFairy_<連番>.pngにします。
拡張子を指定するコードにした理由は統一感と、jpgでは透過(アルファチャンネル)対応していないのでpngに変える必要性が出るためです。

python3 rename.py -n Fairy -o png

./outputを確認すると、Fairy_<連番>.pngにリネームされています。
統一感が出ました。

Screenshot from 2023-05-27 12-23-44.png

おまけ ワンライナーでリネーム

お試しで行ったような簡単なリネームならワンライナーでも可能です。

ls *.png | awk 'BEGIN{ a=1 }{ printf "mv %s Fairy_%d.png\n", $0, a++ }' | sh

ただしワンライナーで|を挟んだ箇所は別個の処理となるため、他の処理が割り込む可能性を考慮してバックアップだけは取っておくことをおすすめします。

余談ですが、awkにはNRという処理中の行番号を表すビルトイン変数があります。
連番に使えそうですが、あくまでNRの値はlsコマンドの出力行数なため行番号の重複でファイルが一部消えます。

※シェルは下記書籍 1 冊読んだだけの門外漢のため、あくまで参考程度に。

最後に

最後まで閲覧頂きありがとうございました。
備忘録の側面もありますが、本記事がお役に立てば幸いです!

参考 URL

8
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?