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

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

## パスが存在するかチェックする
```python
In [1]: import os
```
存在するファイル

```python
In [2]: os.path.exists("./test1/test1.txt")
Out[2]: True
```
存在しないファイル

```python
In [3]: os.path.exists("./test1/test1.doc")
Out[3]: False
```
存在するディレクトリ

```python
In [4]: os.path.exists("./test1")
Out[4]: True
```
存在しないディレクトリ

```python
In [5]: os.path.exists("./test2")
Out[5]: False
```
## ファイルかどうかかチェックする
ファイル

```python
In [6]: os.path.isfile("./test1/test1.txt")
Out[6]: True
```
ディレクトリ

```python
In [7]: os.path.isfile("./test1")
Out[7]: False
```
存在しないファイル

```python
In [8]: os.path.isfile("./test1/test1.doc")
Out[8]: False
```
## ディレクトリかどうかチェックする
ディレクトリ

```python
In [9]: os.path.isdir("./test1")
Out[9]: True
```
ファイル

```python
In [10]: os.path.isdir("./test1/test1.txt")
Out[10]: False
```
存在しないディレクトリ

```python
In [11]: os.path.isdir("./test2")
Out[11]: False
```
### ディレクトリ作成
```python
In [12]: os.mkdir("./test2")

In [13]: ls
test1/  test2/
```
## ファイルコピー
copyfile, copyはメタデータがコピーされないが、copy2はメタデータがコピーされる。copy2を使うとファイルの作成日とかもコピーされるようになるが、copyfile, copyはファイル作成日が新しくなる。

```python
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
```

## ディレクトリごとコピー
新しくフォルダを作成してコピーする場合

```python
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
```
すでにあるフォルダにコピーしようとするとエラーがでる

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

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

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

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

```python
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
```
## ファイル削除
```python
In [33]: os.remove("./test1.txt")

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

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

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

In [15]: ls
test1/
```
フォルダごと中身を削除する場合
フォルダの中身が空でもよい。

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

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

## 特定のファイルだけ削除する
globとremoveの合わせ技

```python
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
```

## ファイル移動

```python
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
```

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

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

In [57]: ls 
test1/  test2/  test2.txt
```
ディレクトリ名の変更

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

In [59]: ls
test1/  test2.txt  test3/
```
## 拡張子取得
```python
In [60]: ftitle, fext = os.path.splitext('/path/to/test1.txt')

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

## ファイルタイトル取得
```python
In [60]: ftitle, fext = os.path.splitext('/path/to/test1.txt')

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

## フルパスからファイル名を取得
```python
In [65]: os.path.basename('/path/to/test1.txt')
Out[65]: 'test1.txt'
```
Linux上でwindowsのpathを扱うとうまくいかない。
もちろんWindows上なら大丈夫

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

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

```python
In [67]: import ntpath

In [68]: ntpath.basename('/path/to/test1.txt')
Out[68]: 'test1.txt'
```
もしWindowsのパスが来ても大丈夫

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

## ディレクトリ名とファイル名に分割
```python
In [70]: os.path.split('/path/to/test1.txt')
Out[70]: ('/path/to', 'test1.txt')
```

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

```python
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')
```

## ディレクトリ名とファイル名を結合
```python
In [74]: os.path.join('/path/to','test1.txt')
Out[74]: '/path/to/test1.txt'
```