Pythonで既存ファイルを考慮してファイル名の連番をつける

2022.12.08

データアナリティクス事業本部のueharaです。

Pythonで連番でファイル名をつけることに関して、「一括でファイル名を付与する/変更する」といった趣旨の記事は沢山出てくるのですが、既存ファイルを考慮して新規作成するファイル名に連番をつけるという処理のサンプルが見つけられなかったので、書いてみたいと思います。

何がしたいのか?

以下のように、dataフォルダにtest_000.txt, test_001.txt, img_000.pngといったようなデータが入っていることを想定します。

.
└ data
 ├ img_000.png
 ├ test_000.txt
 └ test_001.txt

このとき、test.txtを出力する時はファイル名をtest_002.txtとしたいですし、img.pngを出力する時はimg_001.pngとしたいです。

また、aaa.datみたいな未だ存在しないデータを出力するときはaaa_000.datとしたいです。

書いてみた

以下のように書いてみました。

test.py

import glob
import os
import re


def make_filename_by_seq(dirname, filename, seq_digit=3):
    filename_without_ext, ext = os.path.splitext(filename)
    
    pattern = f"{filename_without_ext}_([0-9]*){ext}"
    prog = re.compile(pattern)

    files = glob.glob(
        os.path.join(dirname, f"{filename_without_ext}_[0-9]*{ext}")
    )

    max_seq = -1
    for f in files:
        m = prog.match(os.path.basename(f))
        if m:
            max_seq = max(max_seq, int(m.group(1)))
    
    new_filename = f"{filename_without_ext}_{max_seq+1:0{seq_digit}}{ext}"
    
    return new_filename

第1引数には保存先のディレクトリを、第2引数にはファイル名を、第3引数にはシーケンス番号の桁数を指定するようにします。

第3引数を3とすると000, 001といったような形となり、5とすると00000, 00001といった形となります。

実行例

保存先は冒頭に記載したdataディレクトリ構成を想定します。

先程の関数を利用して、プログラムの実行結果を確認してみます。

print(make_filename_by_seq("./data", "test.txt"))
print(make_filename_by_seq("./data", "img.png"))
print(make_filename_by_seq("./data", "aaa.dat"))

実行結果

test_002.txt
img_001.png
aaa_000.dat

期待通りに動作をしてそうです!

最後に

小ネタでしたが、今回は既存ファイルを考慮して新規作成するファイル名に連番をつけるといった処理をPythonで書いてみました。

ファイル名を一意にする際、基本的には日時等が使用されるケースが多いかと思いますが、上記のように連番を付与したいといった方の参考になりましたら幸いです。