web-dev-qa-db-fra.com

Comment déplacer un fichier dans Python

J'ai jeté un œil à l'interface Python os , mais je suis incapable de localiser une méthode pour déplacer un fichier. Comment ferais-je l'équivalent de $ mv ... en Python?

>>> source_files = '/PATH/TO/FOLDER/*'
>>> destination_folder = 'PATH/TO/FOLDER'
>>> # equivalent of $ mv source_files destination_folder
745
David542

os.rename() ou shutil.move()

Les deux utilisent la même syntaxe:

import os
import shutil

os.rename("path/to/current/file.foo", "path/to/new/destination/for/file.foo")
shutil.move("path/to/current/file.foo", "path/to/new/destination/for/file.foo")

Notez que dans les deux cas, le répertoire dans lequel le nouveau fichier est créé doit déjà exister (mais sous Windows, un fichier portant ce nom ne doit pas exister ou une exception sera déclenchée). Notez également que vous devez inclure le nom du fichier (file.foo] dans les arguments source et destination. S'il est modifié, le fichier sera renommé et déplacé.

Comme indiqué dans les commentaires sur d'autres réponses, shutil.move appelle simplement os.rename dans la plupart des cas. Toutefois, si la destination se trouve sur un disque différent de celui de la source, le fichier source sera copié puis supprimé.

1084
ig0774

Bien que os.rename() et shutil.move() renomment tous deux des fichiers, la commande la plus proche de la commande Unix mv est shutil.move(). La différence est que os.rename() ne fonctionne pas si la source et la destination se trouvent sur des disques différents, tandis que shutil.move() ne se soucie pas du disque sur lequel se trouvent les fichiers.

222
Jim Calfas

Pour os.rename ou shutil.move, vous devez importer le module. Aucun * caractère n'est nécessaire pour obtenir tous les fichiers déplacés.

Nous avons un dossier dans/opt/awesome appelé source avec un fichier nommé awesome.txt.

in /opt/awesome
○ → ls
source
○ → ls source
awesome.txt

python 
>>> source = '/opt/awesome/source'
>>> destination = '/opt/awesome/destination'
>>> import os
>>> os.rename(source, destination)
>>> os.listdir('/opt/awesome')
['destination']

Nous avons utilisé os.listdir pour constater que le nom du dossier avait en fait changé. Voici le shutil ramenant la destination à la source.

>>> import shutil
>>> shutil.move(destination, source)
>>> os.listdir('/opt/awesome/source')
['awesome.txt']

Cette fois, j'ai vérifié dans le dossier source pour m'assurer que le fichier awesome.txt que j'ai créé existait. C'est là :)

Maintenant, nous avons déplacé un dossier et ses fichiers d'une source vers une destination et vice-versa.

32
jmontross

Après Python 3.4, vous pouvez également utiliser la classe pathlib de Path pour déplacer le fichier.

Path("path/to/current/file.foo").rename("path/to/new/destination/for/file.foo")

https://docs.python.org/3.4/library/pathlib.html#pathlib.Path.rename

13
MoonFruit

C'est ce que j'utilise en ce moment:

import os, shutil
path = "/volume1/Users/Transfer/"
moveto = "/volume1/Users/Drive_Transfer/"
files = os.listdir(path)
files.sort()
for f in files:
    src = path+f
    dst = moveto+f
    shutil.move(src,dst)

Maintenant entièrement fonctionnel. J'espère que cela vous aide.

Modifier:

J'ai transformé cela en une fonction qui accepte les répertoires source et de destination, crée le dossier de destination s'il n'existe pas et déplace les fichiers. Permet également de filtrer les fichiers src, par exemple si vous souhaitez uniquement déplacer des images, utilisez le modèle '*.jpg', par défaut, tout ce qui se trouve dans le répertoire est déplacé.

import os, shutil, pathlib, fnmatch

def move_dir(src: str, dst: str, pattern: str = '*'):
    if not os.path.isdir(dst):
        pathlib.Path(dst).mkdir(parents=True, exist_ok=True)
    for f in fnmatch.filter(os.listdir(src), pattern):
        shutil.move(os.path.join(src, f), os.path.join(dst, f))
11
Peter Vlaar

La réponse acceptée n'est pas la bonne, car la question ne concerne pas le changement de nom d'un fichier dans un fichier, mais le déplacement de nombreux fichiers dans un répertoire. shutil.move fera le travail, mais pour cela, os.rename est inutile (comme indiqué dans les commentaires) car la destination doit avoir un nom de fichier explicite.

10
Javier Palacios

Basé sur la réponse décrit ici , utiliser subprocess est une autre option.

Quelque chose comme ça:

subprocess.call("mv %s %s" % (source_files, destination_folder), Shell=True)

Je suis curieux de connaître les avantages et les inconvénients de cette méthode par rapport à shutil. Dans mon cas, j'utilise déjà subprocess pour d'autres raisons et cela semble fonctionner, je suis enclin à m'en tenir à cela.

Est-ce que cela dépend du système peut-être?

1
Bill

C'est une solution qui n'active pas Shell en utilisant mv.

import subprocess

source      = 'pathToCurrent/file.foo'
destination = 'pathToNew/file.foo'

p = subprocess.Popen(['mv', source, destination], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
res = p.communicate()[0].decode('utf-8').strip()

if p.returncode:
    print 'ERROR: ' + res
0
alper