Tengo una lista de 20 nombres de archivo, como ['file1.txt', 'file2.txt', ...]
. Quiero escribir un script de Python para concatenar estos archivos en un nuevo archivo. Podía abrir cada archivo f = open(...)
, leer línea por línea llamando f.readline()
y escribir cada línea en ese nuevo archivo. No me parece muy "elegante", especialmente la parte donde tengo que leer // escribir línea por línea.
¿Hay alguna forma más "elegante" de hacer esto en Python?
python
file-io
concatenation
JJ Beck
fuente
fuente
cat file1.txt file2.txt file3.txt ... > output.txt
. En Python, si no te gustareadline()
, siempre lo hayreadlines()
o simplementeread()
.cat file1.txt file2.txt file3.txt
comando usando elsubprocess
módulo y listo. Pero no estoy seguro sicat
funciona en Windows.with
declaración para asegurarse de que sus archivos estén cerrados correctamente e itere sobre el archivo para obtener líneas, en lugar de usarlasf.readline()
.Respuestas:
Esto debería hacerlo
Para archivos grandes:
Para archivos pequeños:
... y otra interesante en la que pensé :
Lamentablemente, este último método deja algunos descriptores de archivos abiertos, de los cuales el GC debería ocuparse de todos modos. Solo pensé que era interesante
fuente
Uso
shutil.copyfileobj
.Lee automáticamente los archivos de entrada trozo por trozo, lo que es más eficiente y lee los archivos de entrada y funcionará incluso si algunos de los archivos de entrada son demasiado grandes para caber en la memoria:
fuente
for i in glob.glob(r'c:/Users/Desktop/folder/putty/*.txt'):
bueno, reemplacé la declaración for para incluir todos los archivos en el directorio, perooutput_file
comencé a crecer realmente en cientos de gb en muy poco tiempo.Para eso es exactamente la entrada de archivos :
Para este caso de uso, en realidad no es mucho más simple que simplemente iterar sobre los archivos manualmente, pero en otros casos, tener un solo iterador que itera sobre todos los archivos como si fueran un solo archivo es muy útil. (Además, el hecho de que
fileinput
cierre cada archivo tan pronto como esté hecho significa que no es necesariowith
niclose
cada uno, pero eso es solo un ahorro de una línea, no es un gran problema).Hay algunas otras características ingeniosas
fileinput
, como la capacidad de hacer modificaciones in situ de archivos simplemente filtrando cada línea.Como se señaló en los comentarios y se discutió en otra publicación ,
fileinput
para Python 2.7 no funcionará como se indica. Aquí una ligera modificación para hacer que el código sea compatible con Python 2.7fuente
fileinput
les dice que es una forma de convertir un simplesys.argv
(o lo que queda como argumentos después deoptparse
/ etc.) En un gran archivo virtual para scripts triviales, y no piensan usarlo para nada de lo contrario (es decir, cuando la lista no es args de línea de comandos). O aprenden, pero luego se olvidan: sigo descubriéndolo cada año o dos ...for line in fileinput.input()
que no es la mejor manera de elegir en este caso particular: el OP quiere concatenar archivos, no leerlos línea por línea, que es un proceso teóricamente más largo para ejecutarNo sé sobre elegancia, pero esto funciona:
fuente
cat
puede tomar una lista de archivos, por lo que no es necesario llamarla repetidamente. Puedes hacerlo fácilmente llamando al ensubprocess.check_call
lugar deos.system
¿Qué hay de malo con los comandos UNIX? (dado que no está trabajando en Windows):
ls | xargs cat | tee output.txt
hace el trabajo (puede llamarlo desde python con subproceso si lo desea)fuente
cat * | tee output.txt
.cat file1.txt file2.txt | tee output.txt
1> /dev/null
al final del comandoUn punto de referencia simple muestra que el shutil funciona mejor.
fuente
Una alternativa a la respuesta @ inspectorG4dget (la mejor respuesta hasta la fecha 29-03-2016). Probé con 3 archivos de 436MB.
@ inspectorG4dget solución: 162 segundos
La siguiente solución: 125 segundos
La idea es crear un archivo por lotes y ejecutarlo, aprovechando la "tecnología buena y antigua". Es semi-pitón pero funciona más rápido. Funciona para ventanas.
fuente
Si tiene muchos archivos en el directorio, entonces
glob2
podría ser una mejor opción para generar una lista de nombres de archivos en lugar de escribirlos a mano.fuente
Consulte el método .read () del objeto File:
http://docs.python.org/2/tutorial/inputoutput.html#methods-of-file-objects
Podrías hacer algo como:
o una forma de pitón más "elegante":
que, según este artículo: http://www.skymind.com/~ocrow/python_string/ también sería el más rápido.
fuente
Si los archivos no son gigantescos:
Si los archivos son demasiado grandes para leerlos por completo y guardarlos en la RAM, el algoritmo debe ser un poco diferente para leer cada archivo que se copiará en un bucle por fragmentos de longitud fija,
read(10000)
por ejemplo.fuente
os.open
yos.read
, a causa de civilopen
envoltorios usos de Python alrededor de stdio C, lo que significa 1 o 2 amortiguadores adicionales en su camino.fuente
fuente