こんにちは。
今回は、PYTHONを使って、あるフォルダーにある特定のファイルを他のフォルダーに移動させるプログラムを作成してみたいと思います。
プログラム作成に至った理由
ブログのタイトル画像を作成する時はGIMPという描画ソフトを使っています。画像を作成したら、画像をPNGやJPGで出力しています。
ファイルを整理するために、GIMP用のファイル(拡張子xcf)と出力した画像ファイル(PNG、JPG)を、GIMP用、画像用に別々のフォルダに分けて保存していますが、時々、画像用のフォルダにGIMPのファイルを間違って保存してしまうことがあります。
定期的に、画像用のフォルダに間違って保存したGIMPのファイルをGIMP用フォルダに、カットアンドペーストをしていましたが、プログラムで作成した方が、正確で楽だと思い、今回のプログラムを作成することに至りました。
プログラムの内容
今回作成するプログラムは以下になります。
- 『フォルダーA』に拡張子(txt)と拡張子(jpg)のファイルが存在する。
- 拡張子(jpg)のファイルだけを、『フォルダB』に移動させる。
- もし『フォルダB』に同じファイルがある場合、ファイルの更新日時を比較して新しければ上書きをする。
- プログラム最後に、移動処理した場合のメッセージ、移動処理しなかった場合のメッセージを表示する。
ライブラリについて『os』、『pathlib』、『shutil』
使用するライブラリは、『os』、『pathlib』、『shutil』の3つになります。
『os』は、フォルダ内のファイルの有無を調べる為に使用します。
『pathlib』は、ファイルの更新日時を調べる為に使用します。
『shutil』は、ファイルを移動する時に使用します。
これらは標準でインストールされているライブラリになるので、改めてインストールする必要はありません。
プログラムコード
では、プログラムコードの解説を始めます。
import os
import shutil
import pathlib
folder_a = 'C:/Labo/a/' # このフォルダにTXTファイル、JPGファイルが保存されている
folder_b = 'C:/Labo/b/' # このフォルダにJPGファイルを移動する
# フォルダ内のファイルをリスト化する
list1 = os.listdir(folder_a)
# JPGファイルだけをリスト化する
list_jpg = [s for s in list1 if ((".JPG") in s) or ((".jpg") in s)]
# 移動、コピー処理されたかを知る為のシグナル
processsignal = 0
for i in range(len(list_jpg)):
file_a = os.path.join(folder_a, list_jpg[i])
file_b = os.path.join(folder_b, list_jpg[i])
# 移動先に同じファイルがあるかを確認する。
if os.path.isfile(file_b):
time_a = pathlib.Path(file_a).stat().st_mtime
time_b = pathlib.Path(file_b).stat().st_mtime
if(time_a > time_b):
shutil.copyfile(file_a, file_b)
print(list_jpg[i] + "が上書きされました")
processsignal = 1
# 移動先にファイルがなければ、そのまま移動する
else:
shutil.move(file_a, folder_b)
print(list_jpg[i] + "が移動されました")
processsignal = 1
# 処理が行われない場合もコメントする
if(processsignal == 0):
print("コピー、更新するファイルはありませんでした")
1、2、3行目:ライブラリを宣言
6、7行目:参照するフォルダ、移動先のフォルダを定義
10行目:参照するフォルダ内のファイルをリスト化
list1 = os.listdir(folder_a)
os.listdirは、フォルダ内のファイルおよびフォルダをリスト化します。
13行目:拡張子のチェック
list_jpg = [s for s in list1 if ((".JPG") in s) or ((".jpg") in s)]
先ほど作成したリスト「list1」からJPGファイルだけを取り出し、「list_jpg」内にリスト化します。
一般的にJPGファイルは、拡張子が『jpg』もしくは『JPG』の2つが存在する為、この2つの文字列のどちらかが含まれていないかをチェックします。
どちらかの条件の時は『or』を使います。
16行目:ファイル移動処理のシグナルを定義
プログラム終了時にファイルが移動されたかを知る為のシグナルを定義します。
処理がされた場合は「1」、されなかった場合は「0」のままにします。
シグナルを定義することで、ファイル移動処理がされなかった場合も知ることが出来ます。
19から21行目:ファイル比較前準備、ファイルに絶対パスを付加する
for i in range(len(list_jpg)):
file_a = os.path.join(folder_a, list_jpg[i])
file_b = os.path.join(folder_b, list_jpg[i])
JPGのファイル名に、絶対パスを付加します。
「pic1.jpg」 ⇒ 「C:\Labo\a\pic1.jpg」
これは後からするファイルの更新日時の確認の時に必要になるからです。
24~26行目:ファイルの存在確認、更新日時の確認
if os.path.isfile(file_b):
time_a = pathlib.Path(file_a).stat().st_mtime
time_b = pathlib.Path(file_b).stat().st_mtime
os.path.isfileはファイルの存在しているかを確認する関数です。移動先のフォルダに同じファイルが存在していないかを確認する為です。
同じ名前のファイルが存在している場合、それぞれの更新日時をpthlib.Path(ファイル名).stat().st_mtimeを使って調べます。
28~31行目:更新日の比較、上書き処理
if(time_a > time_b):
shutil.copyfile(file_a, file_b)
print(list_jpg[i] + "が上書きされました")
processsignal = 1
それぞれの更新日を比較します。更新日時が新しい方が、数値が大きくなります。
shutil.copyfile(元ファイル、移動先ファイル)を使い上書き処理を行います。
処理がされたので「processsignal」を「1」にします。
33~36行目:ファイルの移動
else:
print("else")
shutil.move(file_a, folder_b)
print(list_jpg[i] + "が移動されました")
processsignal = 1
移動先にファイルが無い場合は、shutil.move(ファイル名、移動先のフォルダ)でファイルを移動させます。
39,40行目:移動処理が無かった場合
移動処理が無かった場合もメッセージを表示させます。
ファイル処理には「os.path.join」でファイルにアクセスを容易に
ファイルの存在、ファイルの更新日、ファイルの上書き、ファイルの移動を使う処理を行いましたが、ファイル名に絶対パスを付けなければなりません。
絶対パスを付ける為には、os.path.join(フォルダ名、ファイル名)を使います。
for i in range(len(list_jpg)):
file_a = folder_a +list_jpg[i]
file_b = folder_b +list_jpg[i]
上記の様に文字列を使っても大丈夫です。但し、この場合は、「folder_a=’C:/Labo/a/‘」と定義されていればですが、最後のスラッシュ「/」を付けておかなければなりません。
しかし、os.path.joinの場合は最後のスラッシュが抜けていても大丈夫という違いがあります。
まとめ
いかがだったでしょうか。
JPGファイルの移動をファイルの拡張子の判別で移動させるプログラムを作成しました。
ファイル名全体をみているので、ファイル名自体に規則性があるものならば、それを条件にファイルの判別も出来ますので応用してみて下さい。
『プログラム作成に至った理由』をご覧いただけたら、おそらく同じようなことをされたいと思われる方が多いのではないでしょうか。フォルダでファイル種類のソートで、カットアンドペーストするのもいいですが、このようにプログラムで動かすと、間違いなく出来るので、楽しいです。
是非、みなさんも色々と応用してくださいね。
「役に立った!」と思れましたら、下のSNSボタンで記事のシェアをしていただけると嬉しいです!
コメント