Python

[Python]ファイル/ディレクトリ操作

毎回調べるの面倒なので、Pythonでファイル/ディレクトリ操作する方法をまとめておく。

パスが存在するかチェックする

In [1]: import os

存在するファイル

In [2]: os.path.exists("./test1/test1.txt")
Out[2]: True

存在しないファイル

In [3]: os.path.exists("./test1/test1.doc")
Out[3]: False

存在するディレクトリ

In [4]: os.path.exists("./test1")
Out[4]: True

存在しないディレクトリ

In [5]: os.path.exists("./test2")
Out[5]: False

ファイルかどうかかチェックする

ファイル

In [6]: os.path.isfile("./test1/test1.txt")
Out[6]: True

ディレクトリ

In [7]: os.path.isfile("./test1")
Out[7]: False

存在しないファイル

In [8]: os.path.isfile("./test1/test1.doc")
Out[8]: False

ディレクトリかどうかチェックする

ディレクトリ

In [9]: os.path.isdir("./test1")
Out[9]: True

ファイル

In [10]: os.path.isdir("./test1/test1.txt")
Out[10]: False

存在しないディレクトリ

In [11]: os.path.isdir("./test2")
Out[11]: False

ディレクトリ作成

In [12]: os.mkdir("./test2")

In [13]: ls
test1/  test2/

ファイルコピー

copyfile, copyはメタデータがコピーされないが、copy2はメタデータがコピーされる。copy2を使うとファイルの作成日とかもコピーされるようになるが、copyfile, copyはファイル作成日が新しくなる。

In [16]: import shutil

In [17]: shutil.copyfile("./test1/test1.txt", "./test2.txt")

In [18]: ls
test1/  test2.txt
In [19]: shutil.copy("./test1/test1.txt", "./test3.txt")

In [20]: shutil.copy2("./test1/test1.txt", "./test4.txt")

In [21]: ls
test1/  test1.txt  test2.txt  test3.txt  test4.txt

ディレクトリごとコピー

新しくフォルダを作成してコピーする場合

In [22]: shutil.copytree("./test1", "./test2")

In [23]: ls
test1/  test1.txt  test2/  test2.txt  test3.txt  test4.txt

In [24]: ls test1
test1.log  test10.txt  test2.txt   test3.log  test30.txt
test1.txt  test2.log   test20.txt  test3.txt  test4.txt

In [25]: ls test2
test1.log  test10.txt  test2.txt   test3.log  test30.txt
test1.txt  test2.log   test20.txt  test3.txt  test4.txt

すでにあるフォルダにコピーしようとするとエラーがでる

In [27]: os.mkdir("./test2")

In [28]: shutil.copytree("./test1", "./test2")

OSError: [Errno 17] File exists: './test2'

すでにあるディレクトリにコピーしたい場合

In [29]: from distutils.dir_util import copy_tree

In [30]: copy_tree("./test1", "./test2")

In [31]: ls test1
test1.log  test10.txt  test2.txt   test3.log  test30.txt
test1.txt  test2.log   test20.txt  test3.txt  test4.txt

In [32]: ls test2
test1.log  test10.txt  test2.txt   test3.log  test30.txt
test1.txt  test2.log   test20.txt  test3.txt  test4.txt

ファイル削除

In [33]: os.remove("./test1.txt")

In [34]: ls
test1/  test2/  test2.txt  test3.txt  test4.txt

ディレクトリ削除

空のディレクトリを削除する場合
ディレクトリの中にファイル等が入っているとエラーが出る

In [14]: os.rmdir("./test2")

In [15]: ls
test1/

フォルダごと中身を削除する場合
フォルダの中身が空でもよい。

In [35]: shutil.rmtree("./test2")

In [36]: ls
test1/  test2.txt  test3.txt  test4.txt

特定のファイルだけ削除する

globとremoveの合わせ技

In [43]: ls test2
test1.log  test10.txt  test2.txt   test3.log  test30.txt
test1.txt  test2.log   test20.txt  test3.txt  test4.txt

In [44]: [os.remove(f) for f in glob.glob("./test2/*.log")]
Out[44]: [None, None, None]

In [45]: ls test2
test1.txt   test2.txt   test3.txt   test4.txt
test10.txt  test20.txt  test30.txt

ファイル移動

In [52]: ls test2
test1.log  test10.txt  test2.txt   test3.log  test30.txt
test1.txt  test2.log   test20.txt  test3.txt  test4.txt

In [53]: shutil.move("./test2/test1.txt", ".")

In [54]: ls
test1/  test1.txt  test2/

In [55]: ls test2
test1.log   test2.log  test20.txt  test3.txt   test4.txt
test10.txt  test2.txt  test3.log   test30.txt

ファイル/ディレクトリ名変更

ファイル名の変更
In [56]: os.rename("./test1.txt", "./test2.txt")

In [57]: ls 
test1/  test2/  test2.txt

ディレクトリ名の変更

In [58]: os.rename("./test2", "./test3")

In [59]: ls
test1/  test2.txt  test3/

拡張子取得

In [60]: ftitle, fext = os.path.splitext('/path/to/test1.txt')

In [62]: fext
Out[62]: '.txt'

ファイルタイトル取得

In [60]: ftitle, fext = os.path.splitext('/path/to/test1.txt')

In [61]: ftitle
Out[61]: '/path/to/test1'

フルパスからファイル名を取得

In [65]: os.path.basename('/path/to/test1.txt')
Out[65]: 'test1.txt'

Linux上でwindowsのpathを扱うとうまくいかない。
もちろんWindows上なら大丈夫

In [66]: os.path.basename('\\path\\to\\test1.txt')
Out[66]: '\\path\\to\\test1.txt'

Linux上でWindowsのパスと扱いたい場合

In [67]: import ntpath

In [68]: ntpath.basename('/path/to/test1.txt')
Out[68]: 'test1.txt'

もしWindowsのパスが来ても大丈夫

In [69]: ntpath.basename('\\path\\to\\test1.txt')
Out[69]: 'test1.txt'

ディレクトリ名とファイル名に分割

In [70]: os.path.split('/path/to/test1.txt')
Out[70]: ('/path/to', 'test1.txt')

Linux上でWindowsのパスと扱いたい場合

In [71]: import ntpath

In [72]: ntpath.split('\\path\\to\\test1.txt')
Out[72]: ('\\path\\to', 'test1.txt')

In [73]: ntpath.split('/path/to/test1.txt')
Out[73]: ('/path/to', 'test1.txt')

ディレクトリ名とファイル名を結合

In [74]: os.path.join('/path/to','test1.txt')
Out[74]: '/path/to/test1.txt'