Pythonで大量のファイル名を変更する方法|Python自動化のできること

ファイルを移動したあと、ファイル名を変更することはありませんか?
そのファイル名が10個以上あったとしたら、もう面倒でたまらないですよね。
Pythonを使えば、一瞬でファイル名を一括変更することが可能です。
なぜなら、Pythonは仕事の自動化が得意だからです。
例えば100個以上のファイルがあっても一瞬でファイル名を変更することができます。
特定の拡張子のみを変更することも可能です。
また、この動画では、ファイルの自動作成の方法についても解説しています。
1000個のテキストファイルの作成であっても一瞬です。
プログラミングの練習で大量のファイル作成が必要なときなどにご利用ください。

Pythonで大量のファイル名を変更する方法|Python自動化のできること

作業用のディレクトリとファイルを生成する

import os
from glob import glob
import datetime

まずライブラリをインポートします。

今回は、os、glob、datetimeというライブラリを使用します。

osモジュールを使うと、ファイルの作成、ファイル名の変更、パスの生成、パスの取得などができます。

globを使うと、指定したフォルダにあるファイル名を一気に取得することができます。
他にも、指定した拡張子のファイル名を一気に取得することなどができます。

datetimeは時刻を扱うモジュールです。
今日の日付や現在の時間を取得することができます。

実行します。

レッスンに入る前に、簡単に用語を2つ解説をします。
1つめはディレクトリという用語です。
ディレクトリとは、簡単にいってしまうとフォルダのことです。
ディレクトリとでてきたら、フォルダと考えてもらえれば良いです。
ちなみに、OSがLinuxでは「ディレクトリ」と呼ばれ、WindowsやMacではフォルダと呼ばれます。

2つめは、パスという単語です。
パスといえば、ディレクトリパスとファイルパスを指すことが多いです。
そして、ディレクトリパスとは、ディレクトリまでのパスのこと。
ファイルパスとは、ディレクトリまでのパスに加えてファイル名まであるもののことをいいます。
この動画では、ファイル名まで含めたパスのことをファイルパスと呼ぶことにします。

current_dir = os.getcwd()
print(current_dir)

それでは、ファイルの自動作成の方法について解説をしていきます。
まず、現在の作業ディレクトリを確認してみましょう。
osモジュールのgetcwdを使います。
getcwdは、get current working directory」の略です。
変数current_dirに代入して、print関数で表示させてみます。
実行します。
現在の作業ディレクトリを確認できました。

sample_dir = os.path.join(current_dir, "sample")
print(sample_dir)

この現在の作業ディレクトリのパスを使って、一階層下にsampleというディレクトリを作ってみましょう。
パスの生成には、path.joinを使います。
path.joinの1つめの引数に、current_dirを記述、2つめの引数にsampleを記述しましょう。
sampleというディレクトリを生成しましょう。
実行します。
sampleというディレクトリパスを生成できました。

os.makedirs(sample_dir, exist_ok = True)

その新しいディレクトリ名を使って、ディレクトリを作成してみましょう。
ディレクトリの作成には、osモジュールのmakedirsを使用します。
似た名前のメソッドとしてmkdirがあります。
mkdirは、同じ名前のディレクトリ名が既に存在している場合に、常に上書きされます。
つまり、そのディレクトリにあったファイルは全て消えます。
一方、makedirsは、同じ名前のディレクトリ名が既に存在している場合に、エラーを出す設定にすることができます。
特にこだわりがない場合はmakedirsを使うのが無難です。
exist_okの引数にTrueを渡すと、同じディレクトリ名があってもそれに上書きして新しいディレクトリを作り、Flaseを渡すとエラーがでます。

from IPython.display import Image
Image("./image01.png")

次に、ファイル名を変更するための大量のファイル作成していきましょう。
アルファベット大文字1つの拡張子なしのファイル、アルファベット2つのファイル名で拡張子がtxtのもの、
アルファベット大文字3つで拡張子がcsvのもの。
これをAからZまで同じパターンで作成をしてみましょう。

chr(65)

まずは、大文字1つの拡張子なしのファイルを作っていきましょう。
数字からアルファベットに変換する方法があるのでそれを利用していきます。
Pythonにもともと入っているchr関数を使います。
chr関数は、ASCIIコードにしたがって、数字から文字や記号に変換します。
ASCIIコード一覧表は、キノコードのウェブサイトに用意しています。
概要欄にURLがありますのでご確認ください。
ASCIIコードによると、65は大文字のAです。
実行してみましょう。
大文字のAが表示されました。

for i in range(65, 91):
     print(chr(i),end=' , ')

65から90はアルファベットの大文字AからZです。
for文で回して、printで表示させてみましょう。
なお、print関数の引数endに値を渡せばよいです。
endのデフォルトは、バックスラッシュnです。
つまり、改行です。
ここに半角スペースの間にカンマを記述しましょう。
実行してみましょう。
改行せずに大文字AからZまで表示できました。
これの仕組みを使ってファイル作成していきましょう。

file_list=[]

for i in range(65, 91):
    file_list.append(chr(i)*1)

print(file_list)

このアフファベットをリストにひとつずつ追加していきましょう。
まず、file_listというリストを定義します。
そして、for文で回してappendで追加していきます。
最後に表示させてみましょう。
実行します。
A~Zまでの大文字アルファベットを追加することができました。

file_list = [chr(i)*1 for i in range(65, 91)]
print(file_list)

新しいリストを生成するときに1行で書く方法ことができます。
リスト内包という書き方です。
先ほどは、AからZまでのリストを作るときに、このように3行となってしまいました。
リスト内包を記述すると、このように1行で書くことができます。
forから右側は、通常のfor文の書き方と同じ。
リスト内包の一番左のiの部分だけで、通常のfor文のappendの役割にを担っています。
実行します。
同じ結果のリストを作成することができました。

print('A'*2)
print('String'*2)

アルファベット2文字のリストも作ってみましょう。
通常だと数字に2をかけると、数字が2倍になりますよね。
Pythonだと文字列に2をかけると、もう1つ同じ文字列が生成されます。
この仕組みを使って、アルファベット2文字のリストも作ってみましょう。
試しにAという大文字に2をかける、Stringという文字列に2をかけてみます。
実行します。
同じ文字列が生成されました。

txt_list = [chr(i)*2 for i in range(65, 91)]
print(txt_list)

したがって、このようにすればアルファベット2文字の文字列のリストが生成されます。
テキストファイルのためのアルファベットにしたいので、txt_listという変数に代入しましょう。

csv_list = [chr(i)*3 for i in range(65, 91)]
print(csv_list)

アルファベット3文字の文字列のリストが生成します。
csvファイルのために作成したいので、csv_listという変数に代入しましょう。

for file_name in file_list:
    create_file = open(os.path.join(sample_dir, file_name), mode='w')
    create_file.write('こんにちは')
    create_file.close()

今まで作成した3つのリストを使って、ファイルを作成してみましょう。
使用するメソッドは、python組み込み関数のopen関数です。

open関数を使うと、ファイルを開いて読み込みだり、書き込んだりという操作をすることができます。
必須の引数は、ファイル名です。
今回はファイルパスをpath.joinを使って、ディレクトリパスが入ったsample_dir、リストに格納されているfile_nameを結合してファイルパスにします。
そして、modeの引数に、ファイルを書き込み用で開くのか、読み込み用に開くのかを渡します。
wだと書き込み用、rだと読み込み用です。
今回は書き込むので、wを渡します。
そして、その生成したオブジェクトをcreate_fileという変数に代入します。

次に、ファイルを書き込む記述です。
実際の書き込みはwriteメソッドで、書き込むことができます。
こんにちはと書き込みましょう。
最後に、closeで開いたファイルを閉じる記述をしましょう。
実行します。
ファイルを作成できました。

for file_name in txt_list:
    create_file = open(os.path.join(sample_dir, file_name + ".txt"), mode='w')
    create_file.write('こんにちは')
    create_file.close()

次は、txtファイルを作ってみましょう。
file_nameのあとに.txtをつけましょう。
実行します。

for file_name in png_list:
    create_file = open(os.path.join(sample_dir, file_name + ".csv"), mode='w')
    create_file.write('こんにちは')
    create_file.close()

次は、csvファイルを作ってみましょう。
file_nameのあとに.csvをつけましょう。
実行します。
作成できました。

path_list=[os.path.join(sample_dir, "AA.txt")]
print(path_list)

まず試しに1つのファイル名だけ変更してみましょう。
具体的には、AA.txtのファイルのみ変更してみます。
ファイルパスをpath_listに代入します。
実行します。
このファイルパスです。

word="test" 
date="20190922"

ファイル名に追加する文字列をwordに代入します。
また日付をdateに代入します。
2019年9月22日を代入しましょう。

for path in path_list:
    dirname, file_and_ext = os.path.split(path)
    file, ext = os.path.splitext(file_and_ext)
    new_file_name = file +"_"+ word + "_" + date + ext
    os.rename(path, os.path.join(dirname, new_file_name))

path_listには、1つのファイルパスしか代入されていませんが、for文を使って1つずつ取り出していきましょう。

2行めのコードでは、ディレクトリとファイル名に分割しています。
osモジュールのpath.splitを使うとディレクトリとファイル名に分けることができます。
['/Users/kinocode/Documents/python/sample/AAA.txt']
のディレクトリだと、AAAより前がディレクトリパス、ファイルがAAA.txtです。
返り値は2つです。
最初の返り値がディレクトリパスで、次の返り値がファイルです。
変数をそれぞれdirname、file_and_extとしましょう。
extは、extension、つまり拡張子の略をとってつけました。

3行めのコードです。
osモジュールのpath.splitextを使うと、ファイル名をファイル名と拡張子に分けることができます。
今回の場合だと、AAAがファイル名。「.txt」が拡張子です。
返り値は2つです。
最初の返り値がファイル名で、次の返り値が拡張子です。
変数をそれぞれfile、extとしましょう。

4行めのコードです。
変更後ファイル名を作成します。
今まで作成した4つの変数を作って、変更後のファイル名を作ります。
1つめは、splitextで取り出したファイル名。
2つめは、変数wordに代入したファイル名に追加したいワード。
3つめは、変数dateに代入した日付。
4つめは、splitextで取り出した拡張子です。
それをnew_file_nameという変数に代入します。
ちなみに、このようなファイル名になります。

最後に、ファイル名を変える処理をします。
osモジュールのrenameを使うと、ファイル名を変更できます。
必須の引数は、2つあります。1つめは変更前のファイル名、2つめは変更後のファイル名です。
ファイル名はディレクトリを前につけて、ファイルパスで指定することができます。
今回はファイルパスで指定します。
変更前のファイルパスは変数pathに代入されています。
変更後のファイルパスは、dirnameと先ほど作ったnew_file_nameを使ってpath.joinで生成します。
実行してみましょう。
ファイル名が変更されました。

path_list = glob(os.path.join(sample_dir, "*.csv"))
word="test"

では、ファイルを一気に変更してみましょう。
sampleディレクトリにあるcsvファイルを一気に変更してみましょう。
まず、sampleディレクトリにあるcsvファイルのファイル名を取得します。 指定したフォルダにある特定のファイルを取得するには、glob(グロブ)関数を使います。
この関数を使うと、拡張子を指定して、指定した拡張子のファイル名を取得することができます。
必須の引数は、ファイルパスです。 csvファイルのみ取得してみましょう。
このように正規表現とセットで記述するとcsvファイルのみ取得することおができます。

2行目は、追加するワードです。
先ほどと同じようにwordという変数に代入をしましょう。

today = datetime.datetime.now()
print(today)

次に、現在の日付と時間を取得します。
現在の日付と時間を取得するには、datetime.now関数を使います。
そして、todayという変数に代入をします。
表示をさせてみましょう。
実行します。
現在の時間を取得できました。

type(today)

このデータ型は日付型です。
日付型の場合、文字列に結合できないので、日付型から文字列型に変換しましょう。

formated_today = today.strftime('%Y%m%d_%H%M')
print(formated_today)

文字列型に変換するにはstrftimeを使います。
どのような文字列に変換するかは丸括弧内の引数で指定することができます。
このように記述すると、 西暦、月、日、時間、分まで表示できます。
sをつけると秒まで付け加えることができますが、今回は分までにしましょう。
実行します。
文字列に変換できました。

これらの変数を使って、ファイルを一気に変更してみましょう。

for path in path_list:
    dirname, file_and_ext = os.path.split(path)
    file, ext = os.path.splitext(file_and_ext)
    new_file_name = file +"_"+ word + "_" + formated_today + ext
    os.rename(path, os.path.join(dirname, new_file_name))

今まで見てきたコードと全く一緒です。
グロブ関数で取得したsampleディレクトリにあるcsvファイルのファイル名が代入されているpath_listを使います。
for文で回して1つずつ取り出していきます。
2行目で、path.splitでディレクトリ名と拡張子つきのファイル名に分割。
3行目で、path.splitextでファイル名と拡張子に分割。
4行目で、新しいファイル名を生成
最後にrenameで変更します。
実行します。
csvファイルのファイル名がすべて変更されました。