Parece que cp no es una llamada al sistema y, por lo tanto, no pertenece al módulo os. Es un comando de shell, por lo que se coloca en el módulo shutil.
waldol1
Respuestas:
3013
shutiltiene muchos métodos que puedes usar. Uno de los cuales es:
from shutil import copyfile
copyfile(src, dst)
Copie el contenido del archivo llamado src a un archivo llamado dst .
La ubicación de destino debe poder escribirse; de lo contrario, se generará una excepción IOError .
Si dst ya existe, será reemplazado.
Los archivos especiales como dispositivos de caracteres o de bloque y tuberías no se pueden copiar con esta función.
Con copy , src y dst son nombres de ruta dados como cadenas .
Si usa os.pathoperaciones, use en copylugar de copyfile. copyfilese acepta solamente cadenas .
en copia (src, dst) el dst puede ser un directorio.
Owen
41
Tenga en cuenta que no todos los metadatos se copiarán, dependiendo de su plataforma.
Kevin Horn
12
Tenga en cuenta que no es una operación atómica. Tenga cuidado al usarlo en una aplicación roscada.
waterbyte
44
Tenga en cuenta que no puede manejar abreviaturas como ~, pero puede tratar con rutas relativas
zwep
1253
┌──────────────────┬────────┬───────────┬───────┬────────────────┐
│ Function │ Copies │ Copies │Can use│ Destination │
│ │metadata│permissions│buffer │may be directory│
├──────────────────┼────────┼───────────┼───────┼────────────────┤
│shutil.copy │ No │ Yes │ No │ Yes │
│shutil.copyfile │ No │ No │ No │ No │
│shutil.copy2 │ Yes │ Yes │ No │ Yes │
│shutil.copyfileobj│ No │ No │ Yes │ No │
└──────────────────┴────────┴───────────┴───────┴────────────────┘
permite dstser un directorio (en lugar del nombre completo del archivo de destino), en cuyo caso el nombre base de srcse usa para crear el nuevo archivo;
conserva la modificación original y la información de acceso (mtime y atime) en los metadatos del archivo (sin embargo, esto viene con una ligera sobrecarga).
Aquí hay un breve ejemplo:
import shutil
shutil.copy2('/src/dir/file.ext','/dst/dir/newname.ext')# complete target filename given
shutil.copy2('/src/file.ext','/dst/dir')# target filename is /dst/dir/file.ext
Estoy tratando de copiar aleatoriamente 100k archivos de 1 millón de archivos. copyfilees considerablemente más rápido quecopy2
Vijay
44
¿estoy en lo cierto al suponer que shutil.copy2('/dir/file.ext', '/new/dir/')(con una barra inclinada después de la ruta de destino) eliminará la ambigüedad sobre si copiar a un nuevo archivo llamado "dir" o colocar el archivo en un directorio con ese nombre?
Zak
1
@Vijay Creo que esta sobrecarga se debe a la copia de los metadatos.
Jonathan H
@Zak No hay ambigüedad si /new/dirhay un directorio existente, vea el comentario de @ MatthewAlpert.
Jonathan H
@Zak Tienes razón, agregar una barra al final elimina la ambigüedad. Si /new/dir/no existe, Python arrojará un IsADirectoryErrorarchivo; de lo contrario, copiará el archivo /new/dir/con el nombre original.
martonbognar
125
Puede usar una de las funciones de copia del shutilpaquete:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━
La función conserva los apoyos acepta copias otras
directorio de permisos dest. archivo de metadatos de obj
"" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "
shutil.copy ✔ ✔ ☐ ☐
shutil.copy2 ✔ ✔ ☐ ✔
shutil.copyfile ☐ ☐ ☐ ☐
shutil.copyfileobj ☐ ☐ ✔ ☐
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━
@lightalchemist Acabo de usar vim como bloc de notas, copié los símbolos Unicode usados de una tabla de wikipedia y copié el resultado en el editor de stackoverflow para el pulido final.
@wim, tienes que comparar mi respuesta con la versión 2017 de la respuesta que has vinculado, que era actual cuando publiqué mi respuesta. Principales diferencias: mi respuesta utiliza encabezados de columna mejores / más descriptivos, el diseño de la tabla no distrae, incluye enlaces directos en la documentación y agregué una columna (es decir, 'acepta el archivo obj').
maxschlepzig
44
OKAY. YMMV, pero creo que los cambios cosméticos y las mejoras menores como esa se realizan mejor como ediciones en las respuestas existentes, en lugar de la duplicación de respuestas.
os.popen(cmd[, mode[, bufsize]])# example# In Unix/Linux
os.popen('cp source.txt destination.txt')# In Windows
os.popen('copy source.txt destination.txt')
subprocess.call(args,*, stdin=None, stdout=None, stderr=None, shell=False)# example (WARNING: setting `shell=True` might be a security-risk)# In Linux/Unix
status = subprocess.call('cp source.txt destination.txt', shell=True)# In Windows
status = subprocess.call('copy source.txt destination.txt', shell=True)
subprocess.check_output(args,*, stdin=None, stderr=None, shell=False, universal_newlines=False)# example (WARNING: setting `shell=True` might be a security-risk)# In Linux/Unix
status = subprocess.check_output('cp source.txt destination.txt', shell=True)# In Windows
status = subprocess.check_output('copy source.txt destination.txt', shell=True)
El uso de comandos de cadena única es un mal estilo de codificación (flexibilidad, confiabilidad y seguridad); en su lugar, use la ['copy', sourcefile, destfile]sintaxis siempre que sea posible, especialmente si los parámetros provienen de la entrada del usuario.
Marcel Waldvogel
8
¿Por qué enumera tantas alternativas malas a las funciones de copia shutil?
maxschlepzig
66
shutil está integrado, no es necesario proporcionar alternativas no portátiles. La respuesta podría mejorarse realmente eliminando las soluciones dependientes del sistema, y después de esa eliminación, esta respuesta es solo una copia de las respuestas existentes / una copia de la documentación.
Jean-François Fabre
3
os.popenestá en desuso por un tiempo ahora. y check_outputno devuelve el estado sino la salida (que está vacía en el caso de copy/cp)
Jean-François Fabre
2
shutil en realidad no copia archivos. Hay una gran advertencia en la parte superior de los documentos . "esto significa que el propietario y el grupo del archivo se pierden, así como las ACL. En Mac OS, la bifurcación de recursos y otros metadatos no se usan. Esto significa que se perderán los recursos y el tipo de archivo y los códigos de creador no serán correctos. En Windows, los propietarios de archivos, las ACL y las secuencias de datos alternativas no se copian ".
gman
96
Copiar un archivo es una operación relativamente sencilla como se muestra en los ejemplos a continuación, pero en su lugar debería usar el módulo shutil stdlib para eso.
def copyfileobj_example(source, dest, buffer_size=1024*1024):"""
Copy a file from source to dest. source and dest
must be file-like objects, i.e. any object with a read or
write method, like for example StringIO.
"""whileTrue:
copy_buffer = source.read(buffer_size)ifnot copy_buffer:break
dest.write(copy_buffer)
Si desea copiar por nombre de archivo, puede hacer algo como esto:
def copyfile_example(source, dest):# Beware, this example does not handle any edge cases!with open(source,'rb')as src, open(dest,'wb')as dst:
copyfileobj_example(src, dst)
Hace un tiempo noté que el módulo se llama shutil (singular) y no shutils (plural), y de hecho está en Python 2.3. Sin embargo, dejo esta función aquí como ejemplo.
pi.
44
Copiar el contenido de un archivo es una operación sencilla. Copiar el archivo con sus metadatos es cualquier cosa menos sencillo, incluso más si quieres ser multiplataforma.
LaC
3
Cierto. Mirando los documentos de shutil, la función copyfile tampoco copiará metadatos.
pi.
3
Sí, no estoy seguro de por qué no copiarías la fuente shutil.copyfileobj. Además, no tiene try, finallyque manejar el cierre de los archivos después de las excepciones. Sin embargo, diría que su función no debería ser responsable de abrir y cerrar los archivos. Eso debería ir en una función de envoltura, como cómo se shutil.copyfileenvuelve shutil.copyfileobj.
ErlVolton
2
El código anterior debe especificar destque se puede escribir:open(dest, 'wb')
Copie el contenido del archivo llamado src a un archivo llamado dst. La ubicación de destino debe poder escribirse; de lo contrario, se generará una excepción IOError. Si dst ya existe, será reemplazado. Los archivos especiales como dispositivos de caracteres o de bloque y tuberías no se pueden copiar con esta función. src y dst son nombres de ruta dados como cadenas.
Eche un vistazo a filesys para todas las funciones de manejo de archivos y directorios disponibles en los módulos estándar de Python.
shutil en realidad no copia archivos. Hay una gran advertencia en la parte superior de los documentos . "esto significa que el propietario y el grupo del archivo se pierden, así como las ACL. En Mac OS, la bifurcación de recursos y otros metadatos no se usan. Esto significa que se perderán los recursos y el tipo de archivo y los códigos de creador no serán correctos. En Windows, los propietarios de archivos, las ACL y las secuencias de datos alternativas no se copian ".
gman
47
Ejemplo de copia de directorio y archivo - De Tim Golden's Python Stuff:
shutil en realidad no copia archivos. Hay una gran advertencia en la parte superior de los documentos . "esto significa que el propietario y el grupo del archivo se pierden, así como las ACL. En Mac OS, la bifurcación de recursos y otros metadatos no se usan. Esto significa que se perderán los recursos y el tipo de archivo y los códigos de creador no serán correctos. En Windows, los propietarios de archivos, las ACL y las secuencias de datos alternativas no se copian ".
gman
19
Para archivos pequeños y que usan solo elementos integrados de Python, puede usar el siguiente one-liner:
with open(source,'rb')as src, open(dest,'wb')as dst: dst.write(src.read())
Como @maxschlepzig mencionó en los comentarios a continuación, esta no es la forma óptima para aplicaciones donde el archivo es demasiado grande o cuando la memoria es crítica, por lo tanto, se debe preferir la respuesta de Swati .
Esto lee el archivo fuente completo en la memoria antes de volverlo a escribir. Por lo tanto, esto desperdicia innecesariamente memoria para todas las operaciones de copia de archivos, excepto las más pequeñas.
maxschlepzig
1
¿Es eso cierto? Creo .read()y .write()están almacenados de forma predeterminada (al menos para CPython).
sonora
@soundstripe, por supuesto, esto es cierto. El hecho de que el objeto de archivo devuelto por open()IO amortiguado, por defecto no le ayuda aquí, porque read()se especifica como: 'Si n es negativo u omitido, lea hasta EOF'. Eso significa que read()devuelve el contenido completo del archivo como una cadena.
maxschlepzig
@maxschlepzig Entiendo tu punto y admito que no estaba al tanto. La razón por la que proporcioné esta respuesta fue en caso de que alguien quisiera hacer una copia de archivo simple usando solo elementos integrados, sin necesidad de importarle un módulo. Por supuesto, la optimización de la memoria no debería ser una preocupación si desea esta opción. De todos modos, gracias por aclarar eso. Actualicé la respuesta en consecuencia.
Esto no es portátil e innecesario, ya que puede usar shutil.
Corey Goldberg
44
Incluso cuando shutilno está disponible, subprocess.run() ( shell=True¡ sin !) Es la mejor alternativa a os.system().
maxschlepzig
1
shutil es más portátil
Hiadore
1
subprocess.run()según lo sugerido por @maxschlepzig es un gran paso adelante al llamar a programas externos. Sin embargo, para mayor flexibilidad y seguridad, use la ['cp', rawfile, 'rawdata.dat']forma de pasar la línea de comando. (Sin embargo, para copiar, shutily se recomiendan amigos antes de llamar a un programa externo).
Marcel Waldvogel
2
intente eso con nombres de archivo con espacios en él.
Jean-François Fabre
11
Para archivos grandes, lo que hice fue leer el archivo línea por línea y leer cada línea en una matriz. Luego, una vez que la matriz alcance un cierto tamaño, agréguela a un nuevo archivo.
for line in open("file.txt","r"):
list.append(line)if len(list)==1000000:
output.writelines(list)del list[:]
Esto parece un poco redundante ya que el escritor debe manejar el almacenamiento en búfer. for l in open('file.txt','r'): output.write(l)debería funcionar encontrar; simplemente configure el búfer de flujo de salida según sus necesidades. o puede ir por los bytes haciendo un bucle de prueba con output.write(read(n)); output.flush()dónde nestá la cantidad de bytes que desea escribir a la vez. ambos tampoco tienen una condición para verificar cuál es un bono.
posee el
1
Sí, pero pensé que tal vez esto podría ser más fácil de entender porque copia líneas enteras en lugar de partes de ellas (en caso de que no sepamos cuántos bytes tiene cada línea).
ytpillai
Muy cierto. La codificación para la enseñanza y la codificación para la eficiencia son muy diferentes.
Esto es horrible Hace un trabajo innecesario sin ninguna buena razón. No funciona para archivos arbitrarios. La copia no es idéntica en bytes si la entrada tiene terminaciones de línea inusuales en sistemas como Windows. ¿Por qué crees que esto podría ser más fácil de entender que una llamada a una función de copia shutil? Incluso cuando se ignora shutil, un simple ciclo de lectura / escritura en bloque (usando IO sin búfer) es sencillo, sería eficiente y tendría mucho más sentido que esto, y por lo tanto seguramente es más fácil de enseñar y comprender.
maxschlepzig
11
from subprocess import call
call("cp -p <file> <file>", shell=True)
Y luego alguien usa el código (accidental o intencionalmente) en un archivo grande ... El uso de funciones de shutilmaneja todos los casos especiales para usted y le da tranquilidad.
Marcel Waldvogel
44
al menos no repite las mismas soluciones una y otra vez.
La idea es buena y el código es hermoso, pero una función adecuada de copy () puede hacer más cosas, como copiar atributos (+ x bit) o, por ejemplo, eliminar los bytes ya copiados en caso de que se encuentre una condición de disco lleno .
Raúl Salinas-Monteagudo
1
Todas las respuestas necesitan explicación, incluso si es una oración. Ninguna explicación establece un mal precedente y no es útil para comprender el programa. ¿Qué pasaría si un novato completo de Python apareciera y viera esto, quisiera usarlo, pero no pudiera porque no lo entienden? Desea ser útil para todos en sus respuestas.
connectyourcharger
1
¿No es eso lo que falta .close()en todos esos open(...)s?
luckydonald
No es necesario .close (), ya que NO ESTAMOS ALMACENANDO el objeto puntero de archivo en ninguna parte (ni para el archivo src ni para el archivo de destino).
Respuestas:
shutil
tiene muchos métodos que puedes usar. Uno de los cuales es:Si usa
os.path
operaciones, use encopy
lugar decopyfile
.copyfile
se acepta solamente cadenas .fuente
~
, pero puede tratar con rutas relativasfuente
copy2(src,dst)
A menudo es más útil quecopyfile(src,dst)
porque:dst
ser un directorio (en lugar del nombre completo del archivo de destino), en cuyo caso el nombre base desrc
se usa para crear el nuevo archivo;Aquí hay un breve ejemplo:
fuente
copyfile
es considerablemente más rápido quecopy2
shutil.copy2('/dir/file.ext', '/new/dir/')
(con una barra inclinada después de la ruta de destino) eliminará la ambigüedad sobre si copiar a un nuevo archivo llamado "dir" o colocar el archivo en un directorio con ese nombre?/new/dir
hay un directorio existente, vea el comentario de @ MatthewAlpert./new/dir/
no existe, Python arrojará unIsADirectoryError
archivo; de lo contrario, copiará el archivo/new/dir/
con el nombre original.Puede usar una de las funciones de copia del
shutil
paquete:Ejemplo:
fuente
En Python, puede copiar los archivos usando
shutil
móduloos
módulosubprocess
módulo1) Copiar archivos usando el
shutil
móduloshutil.copyfile
firmashutil.copy
firmashutil.copy2
firmashutil.copyfileobj
firma2) Copiar archivos usando el
os
móduloos.popen
firmaos.system
firma3) Copiar archivos usando el
subprocess
módulosubprocess.call
firmasubprocess.check_output
firmafuente
['copy', sourcefile, destfile]
sintaxis siempre que sea posible, especialmente si los parámetros provienen de la entrada del usuario.os.popen
está en desuso por un tiempo ahora. ycheck_output
no devuelve el estado sino la salida (que está vacía en el caso decopy/cp
)Copiar un archivo es una operación relativamente sencilla como se muestra en los ejemplos a continuación, pero en su lugar debería usar el módulo shutil stdlib para eso.
Si desea copiar por nombre de archivo, puede hacer algo como esto:
fuente
shutil.copyfileobj
. Además, no tienetry, finally
que manejar el cierre de los archivos después de las excepciones. Sin embargo, diría que su función no debería ser responsable de abrir y cerrar los archivos. Eso debería ir en una función de envoltura, como cómo seshutil.copyfile
envuelveshutil.copyfileobj
.dest
que se puede escribir:open(dest, 'wb')
Utiliza el módulo shutil .
Copie el contenido del archivo llamado src a un archivo llamado dst. La ubicación de destino debe poder escribirse; de lo contrario, se generará una excepción IOError. Si dst ya existe, será reemplazado. Los archivos especiales como dispositivos de caracteres o de bloque y tuberías no se pueden copiar con esta función. src y dst son nombres de ruta dados como cadenas.
Eche un vistazo a filesys para todas las funciones de manejo de archivos y directorios disponibles en los módulos estándar de Python.
fuente
Ejemplo de copia de directorio y archivo - De Tim Golden's Python Stuff:
http://timgolden.me.uk/python/win32_how_do_i/copy-a-file.html
fuente
En primer lugar, hice una exhaustiva hoja de trucos de métodos shutil para su referencia.
En segundo lugar, explique los métodos de copia en ejemplos:
Copie recursivamente un árbol de directorios completo enraizado en src, devolviendo el directorio de destino
fuente
Para archivos pequeños y que usan solo elementos integrados de Python, puede usar el siguiente one-liner:
Como @maxschlepzig mencionó en los comentarios a continuación, esta no es la forma óptima para aplicaciones donde el archivo es demasiado grande o cuando la memoria es crítica, por lo tanto, se debe preferir la respuesta de Swati .
fuente
.read()
y.write()
están almacenados de forma predeterminada (al menos para CPython).open()
IO amortiguado, por defecto no le ayuda aquí, porqueread()
se especifica como: 'Si n es negativo u omitido, lea hasta EOF'. Eso significa queread()
devuelve el contenido completo del archivo como una cadena.Podrías usar
os.system('cp nameoffilegeneratedbyprogram /otherdirectory/')
o como lo hice
¿Dónde
rawfile
está el nombre que había generado dentro del programa?Esta es una solución única para Linux
fuente
shutil
no está disponible,subprocess.run()
(shell=True
¡ sin !) Es la mejor alternativa aos.system()
.subprocess.run()
según lo sugerido por @maxschlepzig es un gran paso adelante al llamar a programas externos. Sin embargo, para mayor flexibilidad y seguridad, use la['cp', rawfile, 'rawdata.dat']
forma de pasar la línea de comando. (Sin embargo, para copiar,shutil
y se recomiendan amigos antes de llamar a un programa externo).Para archivos grandes, lo que hice fue leer el archivo línea por línea y leer cada línea en una matriz. Luego, una vez que la matriz alcance un cierto tamaño, agréguela a un nuevo archivo.
fuente
for l in open('file.txt','r'): output.write(l)
debería funcionar encontrar; simplemente configure el búfer de flujo de salida según sus necesidades. o puede ir por los bytes haciendo un bucle de prueba conoutput.write(read(n)); output.flush()
dónden
está la cantidad de bytes que desea escribir a la vez. ambos tampoco tienen una condición para verificar cuál es un bono.shutil
? Incluso cuando se ignorashutil
, un simple ciclo de lectura / escritura en bloque (usando IO sin búfer) es sencillo, sería eficiente y tendría mucho más sentido que esto, y por lo tanto seguramente es más fácil de enseñar y comprender.fuente
call
es inseguro. Consulte el documento de subprocesos al respecto.A partir de Python 3.5 , puede hacer lo siguiente para archivos pequeños (es decir: archivos de texto, pequeños archivos JPEG):
write_bytes
sobrescribirá lo que haya en la ubicación del destinofuente
shutil
maneja todos los casos especiales para usted y le da tranquilidad.Abra el archivo de origen en modo de lectura y escriba en el archivo de destino en modo de escritura.
fuente
.close()
en todos esosopen(...)
s?Python proporciona funciones integradas para copiar fácilmente archivos utilizando las utilidades Shell del sistema operativo.
El siguiente comando se utiliza para copiar el archivo
El siguiente comando se utiliza para copiar archivos con información de metadatos
fuente
copy
entoncescopystat
para preservar los metadatos del archivo. En Python 3.3+copystat
también copia atributos extendidos.