Edited at

[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'