【python】ファイル保存時に自動でリネームしたい

【python】ファイル保存時に自動でリネームしたい

 プログラム実行中のデータを外部のtextに保存しておく場合に特定のタイミングで別のフォルダに移して保管しておきたいことがあります。今回は対象のファイルにxxx_1、xxx_2・・・・と_1を追加していく自作関数を作ります。

サンプルプログラム

【main.py】

# -*- coding: utf-8 -*-
import os
import sys
import codecs 
from os import path


##自作モジュールのインポート##
m_path = path.join(path.dirname(__file__),"under")
sys.path.append(m_path)
import copy_paste

print("main.py実行")

from_name="test.txt"
to_name="てすと.txt"
to_folda="files"


from_path = path.join(path.dirname(__file__),from_name)
to_path = path.join(path.dirname(__file__),to_folda,to_name)
copy_paste.d_copy_paste(from_path,to_path)


【copy_paste.py】

######↓↓関数の説明↓↓###########
"""
copy_paste.py

 関数 :def d_copy_paste(from_path,to_path):
 機能 :ファイルを移動する。
 機能 :移動先に同じ名前のファイルがあれば_1、_2と数字をつけていく。
 引数 :from_path:コピー元のファイルパス
         to_path:コピー先のファイルパス(同じ名前があればリネームされる)
 戻り値:なし

"""
#####################################


from os import path
import codecs 
import os
import shutil
import sys
####ここまでがimport######

def d_copy_paste(from_path,to_path):
    print("d_copy_past関数実行")
    
    f_path=to_path
    ####保存先フォルダに同じ名前のファイルがあれば末尾に"_数字"をつける####
    f_path2=f_path[0:f_path.rfind("\\")]
    f_name=f_path[f_path.rfind("\\")+1:len(f_path)]
    #print(f_path2)
    #print(f_name)
    files = os.listdir(f_path2)
    #print(files)
    num=0
    while num==0:
        f_extension=f_name[f_name.rfind("."):len(f_name)] ###書き込むファイルの拡張子を抽出
        name=f_name[0:f_name.rfind(".")]###書き込むファイル名を抽出
        count=0 ####条件式の分岐のためにここに必要
        n_count=1
        for i in files:
            #print(i)
            f=i[0:i.rfind(".")]
            #print(f)
            #print(name)
            if f_name==i:
                #print(n_count)
                f_name=name+"_"+str(n_count)+f_extension
                n_count=n_count+1
            else:
                count=count+1
        #print(count)
        #print(len(files))
        #print(f_name)
        if count==len(files):
           num=1
    #print("wile_end")
    ##########################################################################
    
    
    
    ####dirname() 指定されたパスからファイル名を除いたものを返します。 
    w_path = path.join(f_path2,f_name)
    #print(w_path) 
    shutil.copyfile(from_path,w_path)



if __name__ == '__main__':
    from_path = path.join(path.dirname(__file__),"test.txt")
    to_path = path.join(path.dirname(__file__),"test_2.txt")
    a=d_copy_paste(from_path,to_path)

実行結果&解説

 main.pyを実行すると、13行目の「main.py実行」とmain.pyから実行したd_copy_paste.pyの24行目の「d_copy_past関数実行」が表示されます。これはプログラムが動いたかの確認用なので不要であれば消去ください。(今回の実行画面はこのprintの内容しか出ません。)
 mian.pyの15~17行目でコピーするファイルの名前(from_name)と、新ししくつけるファイルの名前(to_name)と保存先のフォルダ(files)を決めます。
 20行目で読み込みファイルのパスを作成。
 21行目で書き込みファイルのパスを作成。
 22行目で自作関数d_copy_pastを実行します。
 ※読み込みファイルとmain.pyを異なるフォルダに置いている場合は21行目を参考にパスにフォルダ名を追加ください。

 d_copy_pastでは渡されたパスをもとに64行目のshutil.copyfileでファイルをコピーし貼り付けを行っています。ここでw_pathはmain.pyの21行目で作成したパスに対して重複確認とリネームを実施(35~56行目参照)したものです。
 32行目で保存先フォルダのファイル名を取り出しています。
 35行目以降のwhileループでフォルダのファイル名と新規で保存しようそしているファイル名(f_name)を比較しています。同じ名前の場合は47行目で保存しようとしているファイル名に_1や_2といった繰り返し回数に応じた文字を追加します。
 54行目で保存先のフォルダと繰り返いし回数が等しくなった時にwhileループから抜け出します。
 詳細は28行目から58行目を参照ください。※動きが分かりにくい場合は#でコメントアウトしたprintを使って動作確認ください。

あとがき

 プログラムを作っているときにテキストに動作結果を保存しておきたい時があったのですが、データが上書き保存されてしまうので自分でリネームのルールを作って保存する関数を作成しました。毎日実行して結果を保存していくようなプログラムに使うと便利だと思います。