J'ai une liste de 20 noms de fichiers, comme ['file1.txt', 'file2.txt', ...]
. Je souhaite écrire un script Python pour concaténer ces fichiers dans un nouveau fichier. Je pourrais ouvrir chaque fichier f = open(...)
, lire ligne par ligne en appelant f.readline()
et écrire chaque ligne dans ce nouveau fichier. Cela ne me paraît pas très "élégant", surtout la partie où je dois lire // écrire ligne par ligne.
Existe-t-il une manière plus "élégante" de faire cela en Python?
python
file-io
concatenation
JJ Beck
la source
la source
cat file1.txt file2.txt file3.txt ... > output.txt
. En python, si vous n'aimez pasreadline()
, il y en a toujoursreadlines()
ou simplementread()
.cat file1.txt file2.txt file3.txt
commande à l'aide dusubprocess
module et vous avez terminé. Mais je ne sais pas sicat
fonctionne dans Windows.with
instruction pour vous assurer que vos fichiers sont correctement fermés et parcourez le fichier pour obtenir des lignes, plutôt que d'utiliserf.readline()
.Réponses:
Cela devrait le faire
Pour les gros fichiers:
Pour les petits fichiers:
… Et un autre intéressant auquel j'ai pensé :
Malheureusement, cette dernière méthode laisse quelques descripteurs de fichiers ouverts, dont le GC devrait de toute façon s'occuper. J'ai juste pensé que c'était intéressant
la source
Utilisez
shutil.copyfileobj
.Il lit automatiquement les fichiers d'entrée bloc par bloc pour vous, ce qui est plus efficace et lit les fichiers d'entrée et fonctionnera même si certains des fichiers d'entrée sont trop volumineux pour tenir en mémoire:
la source
for i in glob.glob(r'c:/Users/Desktop/folder/putty/*.txt'):
Eh bien, j'ai remplacé l'instruction for pour inclure tous les fichiers dans le répertoire, mais j'aioutput_file
commencé à devenir vraiment énorme comme dans des centaines de Go en un temps très rapide.C'est exactement à quoi sert fileinput :
Pour ce cas d'utilisation, ce n'est vraiment pas beaucoup plus simple que de simplement itérer manuellement sur les fichiers, mais dans d'autres cas, avoir un seul itérateur qui itère sur tous les fichiers comme s'il s'agissait d'un seul fichier est très pratique. (De plus, le fait de
fileinput
fermer chaque fichier dès que c'est fait signifie qu'il n'y a pas besoin dewith
ouclose
chacun d'eux, mais ce n'est qu'une économie d'une ligne, pas si grave.)Il existe d'autres fonctionnalités intéressantes
fileinput
, comme la possibilité de modifier sur place des fichiers simplement en filtrant chaque ligne.Comme indiqué dans les commentaires, et discuté dans un autre article ,
fileinput
pour Python 2.7 ne fonctionnera pas comme indiqué. Voici une légère modification pour rendre le code compatible Python 2.7la source
fileinput
font dire que c'est un moyen de transformer un simplesys.argv
(ou ce qui reste comme argument aprèsoptparse
/ etc.) En un gros fichier virtuel pour des scripts triviaux, et ne pense pas à l'utiliser pour quoi que ce soit else (c'est-à-dire lorsque la liste n'est pas des arguments de ligne de commande). Ou ils apprennent, mais oublient ensuite - je continue à le redécouvrir chaque année ou deux…for line in fileinput.input()
n'est pas la meilleure façon de choisir dans ce cas particulier: l'OP veut concaténer des fichiers, pas les lire ligne par ligne, ce qui est un processus théoriquement plus long à exécuterJe ne connais pas l'élégance, mais cela fonctionne:
la source
cat
peut prendre une liste de fichiers, donc pas besoin de l'appeler à plusieurs reprises. Vous pouvez facilement le sécuriser en appelant à lasubprocess.check_call
place deos.system
Quel est le problème avec les commandes UNIX? (étant donné que vous ne travaillez pas sous Windows):
ls | xargs cat | tee output.txt
fait le travail (vous pouvez l'appeler depuis python avec un sous-processus si vous le souhaitez)la source
cat * | tee output.txt
.cat file1.txt file2.txt | tee output.txt
1> /dev/null
à la fin de la commandeUn simple benchmark montre que le shutil fonctionne mieux.
la source
Une alternative à la réponse @ inspectorG4dget (meilleure réponse à ce jour 29-03-2016). J'ai testé avec 3 fichiers de 436 Mo.
@ solution inspectorG4dget: 162 secondes
La solution suivante: 125 secondes
L'idée est de créer un fichier batch et de l'exécuter en tirant parti de la «vieille bonne technologie». Son semi-python mais fonctionne plus vite. Fonctionne pour Windows.
la source
Si vous avez beaucoup de fichiers dans le répertoire, il
glob2
peut être préférable de générer une liste de noms de fichiers plutôt que de les écrire à la main.la source
Découvrez la méthode .read () de l'objet File:
http://docs.python.org/2/tutorial/inputoutput.html#methods-of-file-objects
Vous pouvez faire quelque chose comme:
ou une façon python plus `` élégante '':
qui, selon cet article: http://www.skymind.com/~ocrow/python_string/ serait également le plus rapide.
la source
Si les fichiers ne sont pas gigantesques:
Si les fichiers sont trop gros pour être entièrement lus et conservés en RAM, l'algorithme doit être un peu différent pour lire chaque fichier à copier en boucle par morceaux de longueur fixe, en utilisant
read(10000)
par exemple.la source
os.open
etos.read
, car plainopen
utilise les wrappers de Python autour du stdio de C, ce qui signifie que 1 ou 2 tampons supplémentaires vous gênent.la source
la source