ファイルをフォルダに入れておくと、一括で日付つきのファイル名に変換する Python のスクリプトについてまとめておきます。
以下の環境で動作確認をしています。
環境: Windows、Python 3.X (+ Anaconda)
背景
最近は、ネット銀行、証券、グーグルなどのサイトで、csv ファイルなどのデータをダウンロードできるサービスが増えました。
ところがサイトによっては、ダウンロードしたときのファイル名が、常に同じになっていることがあります。
銀行の明細であれば、ダウンロードする日時によって、明細の内容は異なるのが通常です。にもかかわらず、ファイル名が同一になっていることが多いです。
ファイル名が同一だと、過去にダウンロードしたデータと混ざって上書きして消してしまうことがあります。かといって、今後ずっと、手作業で日付つきファイル名などに修正していく、というのも避けたいところです。
ということで、ダウンロードしたファイルを日付(+時刻)つきのファイル名に一括変更する Python のスクリプトをまとめ、公開しておきます。
私の場合、よくダウンロードするファイルとしては、銀行やクレジットカードの明細、証券会社の明細、Google Trends、レンタルサーバーなどのファイルなどがあります。
ファイルフォーマットとしては、csv、pdf、xls、txt などがあります。
使っているウェブサービスが増えるにつれ、種類も数十を超え、増加しています。
これまで、ファイル名の変更などはサイトごとにプログラムを作るなどしていましたが、ファイルの種類がいつのまにか増え、手作業でのファイル名の修正やドラッグ操作を毎日のように繰り返していました。
そこで、スクリプトを作り直して、過去に扱っていたすべてのファイルを一括変換できるよう汎用化しました。
設定手順
① 以下を参考に、ファイル変換のための作業用のフォルダを作成してください。
c:\user\file_renamer1
② ①のフォルダ内に file_renamer1.py 等の名前でテキストファイルを作成し、下記のサンプルコードを貼りつけて保存してください。
③ ①のフォルダ内に “folder1” という名前でフォルダを作成してください。
使い方
④ ”folder1″ フォルダ内に、ファイル名を修正したいファイル(csv ファイルなど)を入れてください。
最初に使う場合は、テスト用のファイルを試しに入れてみて、うまく変換できるか確認をしてください。
例: test1.csv
⑤ コンソールを起動して②のスクリプトを実行してください。
ファイル名の後半部分に日付時刻を付加して、ファイル名を変換します。
例: test1_210901_123011.csv
※ ファイル名にすでに日付時刻がついていた場合は、変換をスキップします。
スクリプトの説明
・ def file_rename1( file1 ) としたところで、ファイル名を変更する関数を定義しています。
・ スクリプトの入っているパス path1 を取得し、pattern1 としたところで、*.* というパターンとなっているすべてのファイルを取得しています。現状では、csv ファイルであっても、画像ファイル *.bmp, *.jpg 等であっても、*.* のパターンに当てはまるものはすべて、日付つきファイル名に変更します。
もし、csv ファイルだけを抽出したいときは、この部分を *.csv に変更してください。
・ for ループを回し、各ファイルに対して上記の関数 file_rename1() を実行することで変換しています。
・ もし、1つだけのファイルを指定してファイル名を変換したい場合は、for ループを外してしまって、ファイルの絶対パスを file1 で指定して、file_rename1( file1 ) を実行すれば変換できます。
・ 関数 file_rename1() の中では、まず、変換対象となるファイルのパス file1 から、ファイルのタイムスタンプ time1 を取得しています。
つぎに、このタイムスタンプを YYMMDD_HHMMSS の形式に変換し、文字列を作っています。
フルパス file1 を、パスの部分 path2、ファイル名の部分 file2 に分解します。
ファイル名 file2 をファイル名と拡張子に分解し、ファイル名のところに前述の日付の文字列を入れ込み、変換後のファイル名 file3 を生成します。
os.rename( ) としたところで、ファイル名の変換を実行しています。
なお、変換を実行するとき、元のファイル名にすでに日付がついていたときは変換する必要がありません。また、変換後のファイル名がたまたま存在していた場合は、変換をしないほうが安全です。そこで、if 文で、日付の有無と変換後のファイルの有無をチェックし、問題がないときだけファイル名の変換を実行するようにしています。
うまく動いたら
・ うまく動いたら、ファイルを増やしてみるなど活用してみてください。
・ 変換用のフォルダ名 “folder1” は、必要により修正してください。
・ サンプルコードでは、変換するファイルはすべての形式 “*.*” としています。
もし、変換する対象ファイルを csv だけに限定したい等の場合は、pattern1 となっている行のところで、”*.*” を “*.csv” 等に修正してください。
・ 画像や動画のファイル名も一括変換できます。
・ サンプルスクリプトでは、変換後のファイル名は、(元のファイル名)+(年月日)+(時分秒)としています。不要部分があれば、スクリプトで該当部分を削除してください。
YYYY形式、YY形式、日付のみのファイル名、固定したファイル名にするなど、どのようにでもカスタマイズできると思います。
・ 拡張子を変更する場合は、サンプルスクリプト(”# file3 = file3.replace( .. ) となっている行)を参考に、行を追加してください。サンプルコードでは、”.jpeg” の拡張子があった場合は、すべて “.jpg” に統一する事例をコメントとして記載しています。
・ Microsoft Edge ブラウザなどで csv ファイルをダウンロードすると、ダウンロード先はデフォルトで決まっています。変換するフォルダをダウンロード用のフォルダに設定しておけば、ダウンロード後、ファイル名の変換は自動化できることになります。
実用上は、別の Python スクリプトを作っておき、先にファイルを個別のフォルダに移動させてから、フォルダ毎に必要に応じて日付つきファイル名に変更するようにすると便利です。
ある金融のサイトでファイルをダウンロードすると、ファイル名が New_file.csv、SaveFile….csv 等となっており、ファイル名からは内容が不明です。また別のサービスでは、ファイル名が日付時刻のみとなっています。何を保存したのかファイルを開いて内容を確認しないとわかりません。サービスを展開されている方は、こういったところは気にならないのでしょうか。。
まとめ
ファイル名を一括で日付つきに変換する Python のスクリプトについてまとめました。
技術的には、selenium や pyautogui などを使ってサイトのログインのところから自動化し、ダウンロード時にファイル名を指定してもよいです。しかし、パスワード管理など不安なところもありますので、まずは、ダウンロード後、以降の自動化についてまとめました。
なお、ファイル名の変換ではなく、一括で/自動でファイルを移動したいといった場合は、スクリプトを関連リンクにまとめています。もし関心があるようでしたら参照してみてください。
関連リンク
・ 一括でファイルを移動する 【Python】
・ バッチファイルで Anaconda から Python を実行する方法 【Windows 10】
・ 数値を文字列に変換するときによく使うコードまとめ 【Python】
・ ウェブ検索と結果取得を自動化する【Python & selenium】
サンプルコード
import os
import glob as gb1
import datetime as dt1
def file_rename1( file1 ):
time1 = dt1.datetime.fromtimestamp( os.path.getmtime( file1 ) )
ymd1 = "{0:%y%m%d_%H%M%S}".format( time1 )
path2 = os.path.split( file1 )[0] # path
file2 = os.path.split( file1 )[1] # original file name *.csv
file3 = file2.split( "." )[0] + "_" + ymd1 + "." + file2.split( "." )[1] # revised file name
# file3 = file2.split( "_" )[0] + "_" + ymd1 + "." + file2.split( "." )[1] # revised file name
# file3 = file3.replace( ".jpeg", ".jpg" )
file4 = path2 + "/" + file3
if (ymd1 + ".") in file2:
print( "already revised! " + file4 )
elif os.path.isfile( file4 ):
print( "already exists!: " + file4 )
else:
print( "renamed!: " + file4 )
os.rename( file1, file4 ) # rename file
path1 = os.path.dirname(__file__) + "/"
pattern1 = path1 + "folder1/*.*"
files1 = gb1.glob( pattern1 )
for file1 in files1:
file_rename1( file1 )