Pythonでファイル名の前後に文字列や連番を加えて一括変更

osモジュールとglobモジュールを使って一括でリネーム osモジュールとglobモジュールを使って、フォルダ内のファイル名の前後に文字列や連番を加えて一括で変更、リネームします。 ファイル構造の例 以下のようなファイル構造を例とします。今回はフォルダ内にはファイルしかない(フォルダがない)ことが前提。 . └── testdir ├── a.jpg ├── b.jpg ├── c.jpg ├── d.jpg └── e.jpg

注意 ファイル名の変更を伴う処理なので、失敗しても大丈夫なように、オリジナルのファイルは別に保存しておきましょう。 globモジュールでファイルリストを取得

glob モジュールは Unix シェルで使われているルールに従い指定されたパターンに一致するすべてのパス名を見つけ出します。 11.7. glob — Unix 形式のパス名のパターン展開 — Python 3.5.2 ドキュメント

例えば、glob.glob('./*')で、カレントディレクトリ内のファイル名とディレクトリ名のリストが取得できます。引数は絶対パスでも相対パスでも問題ありません。 今回の例だと、

import glob

print(glob.glob('./testdir/*'))
# => ['./testdir/a.jpg', './testdir/b.jpg', './testdir/c.jpg', './testdir/d.jpg', './testdir/e.jpg']

というようになります。 a.jpgではなく./testdir/a.jpgのように、引数のパスが加えられた形で取得できます。 glob.glob('./testdir/.jpg')というようにワイルドカードを使って、特定の拡張子のみを取得することもできます。 以下のパターンマッチが使えます。

*: すべてのものにマッチする ?: 任意の一文字にマッチする [abc]: a, b, cのいずれかの一文字にマッチする [!abc]: a, b, c以外の一文字にマッチする

globモジュールについてのより詳しい説明は

os.rename()でリネーム

os.rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None) ファイルまたはディレクトリ src の名前を dst へ変更します。 16.1. os — 雑多なオペレーティングシステムインタフェース — Python 3.5.2 ドキュメント

名前のとおりリネームしてくれるosモジュールの関数rename()を使います。

import os
os.rename('./testdir/a.jpg', './testdir/a_000.jpg')

とすると、a.jpgがa_000.jpgにリネームされます。

str.format()でゼロ埋めの連番を生成する

例えば、数十個のファイルに連番を加える場合、0や1ではなく、00や01にしたい。このように0埋めしたい場合は、str.format()メソッドを使います。

str.format(args, *kwargs)

文字列の書式化操作を行います。このメソッドを呼び出す文字列は通常の文字、または、 {} で区切られた置換フィールドを含みます。

4. 組み込み型 — Python 3.5.2 ドキュメント書式指定文字列の文法

書式指定文字列は波括弧 {} に囲まれた “置換フィールド” を含みます。

置換フィールドの文法は以下です:

replacement_field ::=  "{" [field_name] ["!" conversion] [":" format_spec] "}"

もっと簡単にいうと、置換フィールドは field_name で始められます。これによって指定したオブジェクトの値が、置換フィールドの代わりに書式化され出力に挿入されます。field_name の後に、感嘆符 '!' を挟んで conversion フィールドを続けることができます。最後にコロン ':' を挟んで、format_spec を書くことができます。これは、置換される値の非デフォルトの書式を指定します。

6.1. string — 一般的な文字列操作 — Python 3.5.2 ドキュメント

とりあえず0埋めしたい場合は以下のようにします。

# 3を2桁でゼロ埋め
print('{0:02d}'.format(3))
# => 03

# 4と6をそれぞれ3桁と4桁でゼロ埋め
print('{0:03d}, {1:04d}'.format(4, 6))
# => 004, 0006

ファイルの前に文字列・連番を追加するコードの例

os.path.basename()でファイル名を取得し、その前に文字列や連番を追加してから、os.path.join()で元のパスと連結します。 以下の例では、すべてのファイル名の前にimg_を追加します。

import os
import glob

path = "./testdir"
files = glob.glob(path + '/*')

for f in files:
    os.rename(f, os.path.join(path, 'img_' + os.path.basename(f)))

結果は以下のようになります。 . └── testdir ├── img_a.jpg ├── img_b.jpg ├── img_c.jpg ├── img_d.jpg └── img_e.jpg

連番を追加する場合はfor文のところをこんな感じに変える。enumerate()でfor文を回すことで、0から順番にカウントされる数値を取得できます。ここでは三桁で0埋めしています。

for i, f in enumerate(files):
    os.rename(f, os.path.join(path, '{0:03d}'.format(i) +
                              '_' + os.path.basename(f)))

結果はこう。 . └── testdir ├── 000_a.jpg ├── 001_b.jpg ├── 002_c.jpg ├── 003_d.jpg └── 004_e.jpg

000からじゃなくて001から始めたい場合は、enumerateの第二引数を1とします。

for i, f in enumerate(files, 1):
    os.rename(f, os.path.join(path, '{0:03d}'.format(i) +
                              '_' + os.path.basename(f)))

こうなります。 . └── testdir ├── 001_a.jpg ├── 002_b.jpg ├── 003_c.jpg ├── 004_d.jpg └── 005_e.jpg

ファイルの後ろに文字列・連番を追加するコードの例

os.path.splitext()で拡張子とルートパスに分割してから、ルートパスの方に文字列や連番を追加します。以下の例では、すべてのファイル名の後に_imgを追加します。

import os
import glob

files = glob.glob('./testdir/*')

for f in files:
    ftitle, fext = os.path.splitext(f)
    os.rename(f, ftitle + '_img' + fext)

結果はこうなります。 . └── testdir ├── a_img.jpg ├── b_img.jpg ├── c_img.jpg ├── d_img.jpg └── e_img.jpg

ファイルの前に文字列・連番を追加するときと同様に、連番を追加する場合はfor文のところを変える。

for i, f in enumerate(files):
    ftitle, fext = os.path.splitext(f)
    os.rename(f, ftitle + '_' + '{0:03d}'.format(i) + fext)

. └── testdir ├── a_000.jpg ├── b_001.jpg ├── c_002.jpg ├── d_003.jpg └── e_004.jpg

Last Updated: 6/26/2019, 10:34:03 PM