¿Cómo muevo un archivo en Python?

7 minutos de lectura

Avatar de usuario de David542
David542

¿Cómo puedo hacer el equivalente de mv en Python?

mv "path/to/current/file.foo" "path/to/new/destination/for/file.foo"

  • para aquellos de ustedes familiarizados con gnu-coreutils’ mv dominiopitón shutil.move tiene un caso de borde donde shutil.move la función difiere. Vaya aquí para una redacción completa. En pocas palabras, Python shutil.move generará una excepción (pero gnu-coreutils mv no lo hará) cuando su destino es un directorio y el directorio ya tiene un archivo con el mismo nombre que el origen (nuevamente, para obtener más información, consulte el enlace proporcionado en la oración anterior).

    – Trevor Boyd Smith

    11 de agosto de 2017 a las 12:22


avatar de usuario de ig0774
ig0774

os.rename(), os.replace()o shutil.move()

Todos emplean la misma sintaxis:

import os
import shutil

os.rename("path/to/current/file.foo", "path/to/new/destination/for/file.foo")
os.replace("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")
  • El nombre del archivo ("file.foo") debe incluirse en los argumentos de origen y destino. Si difiere entre los dos, se cambiará el nombre del archivo y se moverá.
  • El directorio en el que se crea el nuevo archivo ya debe existir.
  • En Windows, no debe existir un archivo con ese nombre o se generará una excepción, pero os.replace() reemplazará silenciosamente un archivo incluso en ese caso.
  • shutil.move simplemente llama os.rename en la mayoría de los casos. Sin embargo, si el destino está en un disco diferente al de origen, copiará y luego eliminará el archivo de origen.

  • ¿Soy el único que piensa que os.rename no funciona para los directorios? Cito: “Si dst es un directorio, se generará OSError”.

    – Fabian

    23 de junio de 2014 a las 20:11


  • shutil.move funciona para directorios. Puedes usar la ruta relativa shutil.move(f.name, "tmp/") o camino completo shutil.move(f.name, "/Users/hello/tmp/"), no utilice ~ en la ruta, marcada en python2.7.9, Mac OS X.

    – por qué es joven

    21 de abril de 2015 a las 2:26


  • ~ es una construcción de shell y no tiene nada que ver con las rutas de archivo en sí, salvo como una convención fuera de lugar. Si realmente quiere involucrar su directorio de inicio, use os.getenv('HOME') en su lugar, concatenarlo con partes de su ruta deseada, si es necesario.

    – Armén Michaeli

    24 de julio de 2015 a las 13:11

  • Siempre puedes usar os.path.expanduser() para expandir adecuadamente el ‘~‘ de acuerdo con las reglas específicas del sistema operativo. Mucho mejor desde %HOME% no siempre está configurado en Windows.

    – ig0774

    24 de julio de 2015 a las 15:27

  • os.rename no manejará archivos a través de diferentes dispositivos. Usar shutil.move si no está seguro de que el archivo de origen y el de destino estén en el mismo dispositivo.

    – Giuseppe Scrivano

    6 de marzo de 2017 a las 11:44

Avatar de usuario de Jim Calfas
Jim Calfas

A pesar de os.rename() y shutil.move() ambos cambiarán el nombre de los archivos, el comando más cercano al comando mv de Unix es shutil.move(). la diferencia es que os.rename() no funciona si el origen y el destino están en discos diferentes, mientras que shutil.move() es independiente del disco de archivos.

  • shutil.move() usos os.rename() si el destino está en el sistema de archivos actual. De lo contrario, shutil.move() copia el origen al destino utilizando shutil.copy2() y luego elimina la fuente.

    – fmalina

    21 de enero de 2014 a las 20:01


  • Cuídate de darte cuenta de que shutil.copy2() no se pueden copiar todos los metadatos del archivoasí que si eso sucede es como hacer cp -p y luego rmdeduzco.

    – 2rs2ts

    01/04/2014 a las 22:01

  • Tenga en cuenta: shutil.move en Python 2.7.3 falla si el destino ya existe. Entonces, si eso es posible, detecte el error o elimine manualmente el archivo / directorio, luego haga el movimiento.

    – dana

    29 mayo 2014 a las 17:44


Avatar de usuario de MoonFruit
LunaFruta

Después de Python 3.4, también puede usar pathlib‘clase S Path para mover el archivo.

from pathlib import Path

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

  • Lo usé recientemente en forma de –> Path("path/to/current/file.foo").rename("path/to/new/destination/for/".joinpath(Path.name)) para mover todos los archivos *.LNK (acceso directo) a un directorio DUMP. ¡Trabajado como un encanto! 😀

    – Amar

    21 de agosto de 2020 a las 0:30

  • Esto funciona perfectamente, pero fallará si desea mover el archivo de un dispositivo a otro (enlace entre dispositivos no válido)

    – capoti

    22 sep 2020 a las 18:50

  • @Amar tal vez esto es mejor. Path("path/to/current/file.foo").rename(Path("path/to/new/destination/for") / Path.name))

    – Fruta de la luna

    16 de abril de 2021 a las 1:56


avatar de usuario de jmontross
jmontross

ya sea para el os.rename o shutil.move tendrá que importar el módulo. No * El carácter es necesario para mover todos los archivos.

Tenemos una carpeta en /opt/awesome fuente llamada con un archivo llamado impresionante.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']

Nosotros usamos os.listdir para ver que el nombre de la carpeta de hecho cambió. Aquí esta la shutil moviendo el destino de regreso a la fuente.

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

Esta vez revisé dentro de la carpeta de origen para asegurarme de que awesome.txt el archivo que creé existe. Está ahí

Ahora hemos movido una carpeta y sus archivos de un origen a un destino y viceversa.

Avatar de usuario de Peter Vlaar
Pedro Vlaar

Esto es lo que estoy usando en este momento:

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)

También puede convertir esto en una función, que acepta un directorio de origen y destino, creando la carpeta de destino si no existe, y mueve los archivos. También permite el filtrado de los archivos src, por ejemplo, si solo desea mover imágenes, entonces usa el patrón '*.jpg'por defecto, mueve todo en el directorio

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))

  • Puede convertir esto fácilmente en un movimiento filtrado usando fnmatch.filter(), vea mi edición. Además, es mejor usar os.path.join(parent_path, filename) en lugar de la concatenación de cadenas para evitar problemas multiplataforma

    – iggy12345

    20 de marzo de 2019 a las 21:13


Avatar de usuario de Javier Palacios
javier palacios

La respuesta aceptada no es la correcta, porque la pregunta no se trata de cambiar el nombre de un archivo a un archivo, sino de mover muchos archivos a un directorio. shutil.move hará el trabajo, pero para este propósito os.rename es inútil (como se indica en los comentarios) porque el destino debe tener un nombre de archivo explícito.

  • Puede convertir esto fácilmente en un movimiento filtrado usando fnmatch.filter(), vea mi edición. Además, es mejor usar os.path.join(parent_path, filename) en lugar de la concatenación de cadenas para evitar problemas multiplataforma

    – iggy12345

    20 de marzo de 2019 a las 21:13


Avatar de usuario de Suraj Rao
Suraj Rao

Como no le importa el valor de retorno, puede hacer

import os
os.system("mv src/* dest/")

¿Ha sido útil esta solución?