Python: ファイルを移動する (shutil.move)

ファイルのETLを実装しているとLinuxのmvコマンド相当のことをよくやるのですが、Pythonではshutil.moveを使うと便利です。

https://docs.python.org/ja/3/library/shutil.html#shutil.move

例としてこのようなディレクトリ構造を仮定します。

% tree
.
├── dir1
│   ├── file1.txt
│   └── file2.txt
└── dir2
    └── file2.txt

ファイルの移動

ファイル名は同じままで、./dir1/file1.txt./dir2に移すときは、第2引数にディレクトリパスを渡すだけでOKです。

  • コピー先のファイルパスが返り値となります
import shutil

new_path = shutil.move("dir1/file1.txt", "dir2")
# -> 'dir2/file1.txt'

ファイル名を変える場合は、ファイルパスを渡します。つまり、第2引数と同じパスのディレクトリが存在する場合はそのディレクトリ内に移動、存在しない場合はファイルとして認識されます。このあたりはmvコマンドになぞらえられてます。

new_path = shutil.move("dir1/file1.txt", "dir2/new_file1.txt")
# -> 'dir2/new_file1.txt'

同名のファイルがすでに存在する場合、上書きされるかどうかは、第2引数に指定されているパスによって異なります。

第2引数がディレクトリパスの場合、例外となってファイルは移動されません。

shutil.move("dir1/file2.txt", "dir2")
>>> Traceback (most recent call last):
...
>>> shutil.Error: Destination path 'dir2/file2.txt' already exists

一方、ファイルパスなら上書きされます。例外も送出されません。

new_path = shutil.move("dir1/file2.txt", "dir2/file2.txt")
# -> 'dir2/file2.txt'

ディレクトリの移動

ディレクトリの移動もmove関数でできます。

new_path = shutil.move("dir1", "dir2")
# -> 'dir2/dir1'

まるっと同じディレクトリ構造で移動されます。

% tree
.
└── dir2
    ├── dir1
    │   ├── file1.txt
    │   └── file2.txt
    └── file2.txt