【Python】ファイルやディレクトリを移動する方法!shutil.move()の使い方!

この記事では、Pythonのディレクトリやファイルを移動する関数『shutil.move()』について、以下の内容を詳しく説明します。

  • shutil.move()とは
  • shutil.move()の構文
  • shutil.move()の使い方
    • ファイルを移動する方法
    • ディレクトリを移動する方法
    • ファイルを移動してリネームする方法
    • ディレクトリを移動してリネームする方法
  • shutil.move()のオプション
    • copy_function引数
  • shutil.move()の注意点
    • ファイルの移動先に存在しない中間ディレクトリがあるとエラーになる
    • ファイルの移動先に新規のディレクトリパスを指定しても、ディレクトリは作成されない
    • ディレクトリの移動先に新規のファイルパスを指定しても、ファイルは作成されない
    • shutil.move()の第1引数に存在しないファイルパスを指定するとエラーになる
    • shutil.move()の第1引数に存在しないディレクトリパスを指定するとエラーになる

などをサンプルコードを用いて分かりやすく説明するように心掛けています。ご参考になれば幸いです。

shutil.move()とは

shutil.move()は、Pythonの標準ライブラリshutilに含まれる関数で、ファイルやディレクトリ(フォルダ)を移動する際に使用されます。この関数を使うと、指定したファイルやディレクトリを新しい場所に移動することができます。

後ほどshutil.move()の構文や使い方について詳しく説明しますが、まず以下に示す簡単なサンプルコードを見てみましょう。

import shutil

# 移動するファイルパスと移動先のディレクトリパス
src_path = 'test_dir/file.txt'
dst_path = 'new_dir'

# shutil.move()でファイルを移動する
shutil.move(src_path, dst_path)

上記のサンプルコードを実行すると、test_dirディレクトリにあるfile.txtnew_dirディレクトリに移動されます。

公式ドキュメント

shutil.move()の公式ドキュメントのリンクを以下に示します。

この記事ではshutil.move()の「使い方」や「オプション」について、サンプルコードを用いてできる限り分かりやすく説明しています。これらの関数の詳細を知りたい方は、公式ドキュメントをご覧ください。

shutil.move()の構文

shutil.move()の構文を以下に示します。

構文

shutil.move(src, dst, copy_function=shutil.copy2)

shutil.move()の引数と返り値を以下に示します。

引数

  • src
    • 移動するファイルやディレクトリのパスです。
  • dst
    • 移動先のファイルやディレクトリのパスです。
  • copy_function(省略可能)
    • ファイルをコピーするために使用される関数です。デフォルトではshutil.copy2を用いてファイルがコピーされます。
    • 必要に応じてカスタムのコピー関数を指定することもできます。

返り値(戻り値)

  • shutil.move()は、移動先のパスを返します。

shutil.move()の使い方

shutil.move()について、以下に示している使い方をこれから説明します。

  • ファイルを移動する方法
    • ファイルの移動先に同名のファイルが存在する場合にはエラーになる
    • ファイルの移動先に既存のファイルパスを指定した場合は上書きされる
  • ディレクトリを移動する方法
    • ディレクトリの移動先に同名のディレクトリが存在する場合にはエラーになる
    • ディレクトリの移動先に既存のファイルパスを指定した場合はエラーになる
  • ファイルを移動してリネームする方法
  • ディレクトリを移動してリネームする方法

上記の使い方について順番に説明します。

ファイルを移動する方法

shutil.move()の第1引数srcに既存のファイルパス、第2引数dstに移動先のファイルパスまたはディレクトリパスを指定すると、そのファイルが移動されます。移動先のファイルパスに既存のファイルを指定した場合は上書きされます。

以下にディレクトリ構造とサンプルコードを示します。

ディレクトリ構造

test_dir/
├── dir1/
│   └── file.txt
└── dir2/

このディレクトリ構造において、以下のサンプルコードを実行します。

サンプルコード

import shutil

# 移動するファイルパスと移動先のディレクトリパス
src_path = 'test_dir/dir1/file.txt'
dst_path = 'test_dir/dir2'

# ファイルを移動する
shutil.move(src_path, dst_path)

上記のサンプルコード実行後のディレクトリ構造

test_dir/
├── dir1/
└── dir2/
    └── file.txt ← 「test_dir/dir1/file.txt」が「test_dir/dir2」に移動される

上記のサンプルコードを実行すると、test_dir/dir1/file.txttest_dir/dir2に移動されます。なお、ディレクトリ指定時の末尾の区切り文字(/)はあってもなくても構いません。そのため、dst_path = 'test_dir/dir2/'のように指定しても大丈夫です。

また、以下のサンプルコードに示すように、第2引数dstにファイルパスを指定しても、ファイルを移動させることができます。その際、ファイル名は第2引数dstで指定したファイルパスのファイル名となります。サンプルコードを以下に示します。

サンプルコード

import shutil

# 移動するファイルパスと移動先のファイルパス
src_path = 'test_dir/dir1/file.txt'
dst_path = 'test_dir/dir2/new_file.txt'

# ファイルを移動する
shutil.move(src_path, dst_path)

上記のサンプルコード実行後のディレクトリ構造

test_dir/
├── dir1/
└── dir2/
    └── new_file.txt  ← 「test_dir/dir1/file.txt」が「test_dir/dir2」に移動され、「new_file.txt」という名前になる

ファイルの移動先に同名のファイルが存在する場合にはエラーになる

shutil.move()の第2引数dstに指定したディレクトリパスに同名のファイルが存在した場合にはエラーになります。

以下にディレクトリ構造とサンプルコードを示します。

ディレクトリ構造

test_dir/
├── dir1/
│   └── file.txt
└── dir2/
    └── file.txt

このディレクトリ構造において、以下のサンプルコードを実行します。

サンプルコード

import shutil

# 移動するファイルパスと移動先のディレクトリパス
src_path = 'test_dir/dir1/file.txt'
dst_path = 'test_dir/dir2' # dir2に同名のファイル(file.txt)が存在している!!

# ファイルを移動する
shutil.move(src_path, dst_path)

エラーメッセージ

shutil.Error: Destination path 'test_dir/dir2\file.txt' already exists

ファイルの移動先に既存のファイルパスを指定した場合は上書きされる

shutil.move()の第2引数dstに既存のファイルパスを指定した場合には、上書きされます。

以下にディレクトリ構造とサンプルコードを示します。

ディレクトリ構造

test_dir/
├── dir1/
│   └── file.txt
└── dir2/
    └── file.txt

このディレクトリ構造において、以下のサンプルコードを実行します。

サンプルコード

import shutil

# 移動するファイルパスと移動先のファイルパス
src_path = 'test_dir/dir1/file.txt'
dst_path = 'test_dir/dir2/file.txt' # 既存のファイルパスを指定している!!

# ファイルを移動する
shutil.move(src_path, dst_path)

上記のサンプルコード実行後のディレクトリ構造

test_dir/
├── dir1/
└── dir2/
    └── file.txt ← file.txtが上書きされる

ディレクトリを移動する方法

shutil.move()の第1引数srcに既存のディレクトリパス、第2引数dstに移動先のディレクトリパスを指定すると、ディレクトリが移動されます。

以下にディレクトリ構造とサンプルコードを示します。

ディレクトリ構造

test_dir/
├── dir1/
│   └── sub_dir/
│       └── sub_file.txt
└── dir2/

このディレクトリ構造において、以下のサンプルコードを実行します。

サンプルコード

import shutil

# 移動するディレクトリパスと移動先のディレクトリパス
src_path = 'test_dir/dir1/sub_dir'
dst_path = 'test_dir/dir2'

# ディレクトリを移動する
shutil.move(src_path, dst_path)

上記のサンプルコード実行後のディレクトリ構造

test_dir/
├── dir1/
└── dir2/
    └── sub_dir/
        └── sub_file.txt ← 「test_dir/dir1/sub_dir」が「test_dir/dir2」に移動される

上記のサンプルコードを実行すると、test_dir/dir1/sub_dirtest_dir/dir2に移動されます。

ディレクトリの移動先に同名のディレクトリが存在する場合にはエラーになる

shutil.move()の第2引数dstにディレクトリパスを指定し、そのディレクトリに同名のディレクトリが存在した場合にはエラーになります。

以下にディレクトリ構造とサンプルコードを示します。

ディレクトリ構造

test_dir/
├── dir1/
│   └── sub_dir/
│       └── sub_file.txt
└── dir2/
    └── sub_dir/

このディレクトリ構造において、以下のサンプルコードを実行します。

サンプルコード

import shutil

# 移動するディレクトリパスと移動先のディレクトリパス
src_path = 'test_dir/dir1/sub_dir'
dst_path = 'test_dir/dir2' # dir2には同名のディレクトリ(sub_dir)が存在している!!

# ディレクトリを移動する
shutil.move(src_path, dst_path)

エラーメッセージ

shutil.Error: Destination path 'test_dir/dir2\sub_dir' already exists

ディレクトリの移動先に既存のファイルパスを指定した場合はエラーになる

shutil.move()の第1引数srcに既存のディレクトリパスを指定し、第2引数dstに既存のファイルパスを指定した場合にはエラーになります。

以下にディレクトリ構造とサンプルコードを示します。

ディレクトリ構造

test_dir/
├── dir1/
│   └── sub_dir/
│       └── sub_file.txt
└── dir2/
    └── file.txt

このディレクトリ構造において、以下のサンプルコードを実行します。

サンプルコード

import shutil

# 移動するディレクトリパスと移動先のファイルパス
src_path = 'test_dir/dir1/sub_dir'
dst_path = 'test_dir/dir2/file.txt' # 既存のファイルパスを指定している!!

# ディレクトリを移動する
shutil.move(src_path, dst_path)

エラーメッセージ

FileExistsError: [WinError 183] 既に存在するファイルを作成することはできません。: 'test_dir/dir2/file.txt'

ファイルを移動してリネームする方法

shutil.move()の第1引数srcにファイルパスを指定し、第2引数dstに新規のファイルパス(存在しないファイルパス)を指定した場合には移動してリネームされます。その際、ファイル名は第2引数dstで指定したファイルパスのファイル名となります。サンプルコードを以下に示します。

以下にディレクトリ構造とサンプルコードを示します。

ディレクトリ構造

test_dir/
├── dir1/
│   └── file.txt
└── dir2/

このディレクトリ構造において、以下のサンプルコードを実行します。

サンプルコード

import shutil

# 移動するファイルパスと移動先のファイルパス
src_path = 'test_dir/dir1/file.txt'
dst_path = 'test_dir/dir2/new_file.txt'

# ファイルを移動する
shutil.move(src_path, dst_path)

上記のサンプルコード実行後のディレクトリ構造

test_dir/
├── dir1/
└── dir2/
    └── new_file.txt ← 「test_dir/dir1/file.txt」が「test_dir/dir2」に移動され、「new_file.txt」という名前になる

ディレクトリを移動してリネームする方法

shutil.move()の第1引数srcにディレクトリパスを指定し、第2引数dstに新規のディレクトリパス(存在しないディレクトリパス)を指定した場合には移動してリネームされます。その際、ディレクトリ名は第2引数dstで指定したディレクトリパスのディレクトリ名となります。

以下にディレクトリ構造とサンプルコードを示します。

ディレクトリ構造

test_dir/
├── dir1/
│   └── sub_dir/
│       └── sub_file.txt
└── dir2/

このディレクトリ構造において、以下のサンプルコードを実行します。

サンプルコード

import shutil

# 移動するディレクトリパスと移動先のディレクトリパス
src_path = 'test_dir/dir1/sub_dir'
dst_path = 'test_dir/dir2/new_sub_dir'

# ディレクトリを移動する
shutil.move(src_path, dst_path)

上記のサンプルコード実行後のディレクトリ構造

test_dir/
├── dir1/
│   └── file.txt
└── dir2/
    └── new_sub_dir/ ← 「test_dir/dir1/sub_dir」が「test_dir/dir2」に移動され、「new_sub_dir」いう名前になる
        └── sub_file.txt

shutil.move()のオプション

shutil.move()に使用できる以下のオプションについて詳しく説明します。

  • copy_function引数

copy_function引数

copy_functionは「ファイルをコピーするために使用する関数」を指定する引数です。デフォルトは shutil.copy2 であり、可能な限りメタデータもコピーします。必要に応じてカスタムのコピー関数を指定できます。

以下に、ディレクトリ構造とcopy_function引数を指定したサンプルコードを示します。

ディレクトリ構造

test_dir/
├── dir1/
│   └── file.txt
└── dir2/

このディレクトリ構造において、以下のサンプルコードを実行します。

サンプルコード

import shutil

# 移動するファイルパスと移動先のディレクトリパス
src_path = 'test_dir/dir1/file.txt'
dst_path = 'test_dir/dir2'

# ファイルをコピーするためのカスタム関数
def custom_copy(src, dst):
    print(f"Copying {src} to {dst}")
    shutil.copy(src, dst)

# ファイルを移動する際にカスタムのコピー関数を使用する
shutil.move(src_path, dst_path, copy_function=custom_copy)

上記のサンプルコード実行後のディレクトリ構造

test_dir/
├── dir1/
└── dir2/
    └── file.txt ← shutil.copyを用いてファイルをコピー

上記のサンプルコードでは、ファイルを移動する際にカスタムのコピー関数custom_copyが使用されます。また、カスタムのコピー関数custom_copy内部の処理ではshutil.copy2ではなく、shutil.copyを用いてファイルをコピーしています。

あわせて読みたい

shutil.copy()shutil.copy2()については下記の記事で詳しく説明しています。興味のある方は下記のリンクからぜひチェックをしてみてください。

shutil.move()の注意点

shutil.move()の注意点を以下に示します。

  • ファイルの移動先に存在しない中間ディレクトリがあるとエラーになる
  • ファイルの移動先に新規のディレクトリパスを指定しても、ディレクトリは作成されない
  • ディレクトリの移動先に新規のファイルパスを指定しても、ファイルは作成されない
  • shutil.move()の第1引数に存在しないファイルパスを指定するとエラーになる
  • shutil.move()の第1引数に存在しないディレクトリパスを指定するとエラーになる

各注意点について順番に説明します。

ファイルの移動先に存在しない中間ディレクトリがあるとエラーになる

shutil.move()の第1引数srcにファイルパスを指定し、第2引数dstに存在しない中間ディレクトリがあるパスを指定した場合にはエラーが発生します。

以下に、ディレクトリ構造とサンプルコードを示します。

ディレクトリ構造

test_dir/
├── dir1/
│   └── file.txt
└── dir2/

このディレクトリ構造において、以下のサンプルコードを実行します。

サンプルコード

import shutil

# 移動するファイルパスと移動先のディレクトリパス
src_path = 'test_dir/dir1/file.txt'
dst_path = 'test_dir/dir2/new_dir/file.txt' # new_dirは存在しない中間ディレクトリ!!

# ファイルを移動する
shutil.move(src_path, dst_path)

エラーメッセージ

FileNotFoundError: [WinError 3] 指定されたパスが見つかりません。

なお、shutil.move()の第1引数srcにディレクトリパスを指定した場合は、第2引数dstに存在しない中間ディレクトリがあるパスを指定してもエラーが発生しません。

サンプルコード

import shutil

# 移動するディレクトリパスと移動先のディレクトリパス
src_path = 'test_dir/dir1'
dst_path = 'test_dir/dir2/new_dir/new_dir2' # new_dirは存在しない中間ディレクトリ!!

# ディレクトリを移動する
shutil.move(src_path, dst_path)

上記のサンプルコード実行後のディレクトリ構造

test_dir/
└── dir2/
    └── new_dir/
        └── new_dir2/ ← 「test_dir/dir1」が「test_dir/dir2/new_dir」にコピーされ、「new_dir2」という名前になる。
            └── file.txt

ファイルの移動先に新規のディレクトリパスを指定しても、ディレクトリは作成されない

shutil.move()の第1引数srcにファイルパスを指定し、第2引数dstに新規のディレクトリパスを指定しても、ディレクトリは作成されません。例えば、test_dir/dir3と指定すると、test_dir/dir3の中にファイルが移動されるのではなく、dir3というファイルとしてリネームされて移動されるので注意してください。

以下に、ディレクトリ構造とサンプルコードを示します。

ディレクトリ構造

test_dir/
├── dir1/
│   └── file.txt
└── dir2/

このディレクトリ構造において、以下のサンプルコードを実行します。

サンプルコード

import shutil

# 移動するファイルパスと移動先のディレクトリパス
src_path = 'test_dir/dir1/file.txt'
dst_path = 'test_dir/dir3' # ファイルの移動先に新規のディレクトリパスを指定している!!

# ファイルを移動する
shutil.move(src_path, dst_path)

上記のサンプルコード実行後のディレクトリ構造

test_dir/
├── dir1/
├── dir2/
└── dir3 ← 「test_dir/dir1/file.txt」が「test_dir」にコピーされ、「dir3」という名前になる。

ディレクトリの移動先に新規のファイルパスを指定した場合はエラーにはならず、ディレクトリが作成される

shutil.move()の第1引数srcにディレクトリパスを指定し、第2引数dstに新規のファイルパスを指定しても、ファイルは作成されません。ディレクトリが作成されてしまいます(第2引数dstで指定したファイル名がディレクトリ名なります)。

以下にディレクトリ構造とサンプルコードを示します。

ディレクトリ構造

test_dir/
├── dir1/
│   └── sub_dir/
│       └── sub_file.txt
└── dir2/

このディレクトリ構造において、以下のサンプルコードを実行します

サンプルコード

import shutil

# 移動するディレクトリパスと移動先のファイルパス
src_path = 'test_dir/dir1/sub_dir'
dst_path = 'test_dir/dir2/new_file.txt' # ディレクトリの移動先に新規のファイルパスを指定している!!

# ディレクトリを移動する
shutil.move(src_path, dst_path)

上記のサンプルコード実行後のディレクトリ構造

test_dir/
├── dir1/
└── dir2/
    └── new_file.txt/ ← 「test_dir/dir1/sub_dir」が「test_dir/dir2」にコピーされ、「new_file.txt」という名前になる。
        └── sub_file.txt

shutil.move()の第1引数に存在しないファイルパスを指定するとエラーになる

shutil.move()の第1引数srcに存在しないファイルパスを指定した場合にはエラーが発生します。

以下にディレクトリ構造とサンプルコードを示します。

ディレクトリ構造

test_dir/
├── dir1/
│   └── file.txt
└── dir2/

このディレクトリ構造において、以下のサンプルコードを実行します

サンプルコード

import shutil

# 移動するファイルパスと移動先のディレクトリパス
src_path = 'test_dir/dir1/hogehoge.txt' # 存在しないファイルパスを指定している!!
dst_path = 'test_dir/dir2' 

# ファイルを移動する
shutil.move(src_path, dst_path)

エラーメッセージ

FileNotFoundError: [WinError 2] 指定されたファイルが見つかりません。

shutil.move()の第1引数に存在しないディレクトリパスを指定するとエラーになる

shutil.move()の第1引数srcに存在しないディレクトリパスを指定した場合にはエラーが発生します。

以下に、ディレクトリ構造とサンプルコードを示します。

ディレクトリ構造

test_dir/
├── dir1/
│   └── sub_dir/
│       └── sub_file.txt
└── dir2/

このディレクトリ構造において、以下のサンプルコードを実行します

サンプルコード

import shutil

# 移動するディレクトリパスと移動先のディレクトリパス
src_path = 'test_dir/dir1/hogehoge_dir' # 存在しないディレクトリパスを指定している!!
dst_path = 'test_dir/dir2' 

# ディレクトリを移動する
shutil.move(src_path, dst_path)

エラーメッセージ

FileNotFoundError: [WinError 2] 指定されたファイルが見つかりません。

本記事のまとめ

この記事では、Pythonのディレクトリやファイルを移動する関数『shutil.move()』について、以下の内容を説明しました。

  • shutil.move()とは
  • shutil.move()の構文
  • shutil.move()の使い方
    • ファイルを移動する方法
    • ディレクトリを移動する方法
    • ファイルを移動してリネームする方法
    • ディレクトリを移動してリネームする方法
  • shutil.move()のオプション
    • copy_function引数
  • shutil.move()の注意点
    • ファイルの移動先に存在しない中間ディレクトリがあるとエラーになる
    • ファイルの移動先に新規のディレクトリパスを指定しても、ディレクトリは作成されない
    • ディレクトリの移動先に新規のファイルパスを指定しても、ファイルは作成されない
    • shutil.move()の第1引数に存在しないファイルパスを指定するとエラーになる
    • shutil.move()の第1引数に存在しないディレクトリパスを指定するとエラーになる

お読み頂きありがとうございました。