Текстовые файлы для конкатенации Python

У меня есть список из 20 имен файлов, таких как ['file1.txt', 'file2.txt', ...] . Я хочу написать скрипт Python, чтобы объединить эти файлы в новый файл. Я мог бы открыть каждый файл с помощью f = open(...) , читать строки за строкой, вызывая f.readline() и записывая каждую строку в этот новый файл. Мне это не кажется очень «изящным», особенно тем, что мне нужно читать // писать по строкам.

Есть ли более «элегантный» способ сделать это в Python?

  • Надежное обнаружение загрузки страницы или тайм-аута, Selenium 2
  • Python: выполнение команды оболочки
  • Кроссплатформенный кейлоггер
  • Какой самый быстрый способ извлечь день, месяц и год с определенной даты?
  • Извлечь информацию о трассировке из объекта исключения
  • Сравнение нескольких переменных с одним и тем же значением в «if» в Python?
  • Pandas написать таблицу для MySQL
  • Коллекции Python.Counter: most_common complex
  • 10 Solutions collect form web for “Текстовые файлы для конкатенации Python”

    Это должно сделать это

    Для больших файлов:

     filenames = ['file1.txt', 'file2.txt', ...] with open('path/to/output/file', 'w') as outfile: for fname in filenames: with open(fname) as infile: for line in infile: outfile.write(line) 

    Для небольших файлов:

     filenames = ['file1.txt', 'file2.txt', ...] with open('path/to/output/file', 'w') as outfile: for fname in filenames: with open(fname) as infile: outfile.write(infile.read()) 

    … и еще один интересный, о котором я думал :

     filenames = ['file1.txt', 'file2.txt', ...] with open('path/to/output/file', 'w') as outfile: for line in itertools.chain.from_iterable(itertools.imap(open, filnames)): outfile.write(line) 

    К сожалению, этот последний метод оставляет несколько открытых файловых дескрипторов, которые GC должен позаботиться о любом случае. Я просто подумал, что это интересно

    Используйте shutil.copyfileobj . Это должно быть более эффективным.

     with open('output_file.txt','wb') as wfd: for f in ['seg1.txt','seg2.txt','seg3.txt']: with open(f,'rb') as fd: shutil.copyfileobj(fd, wfd, 1024*1024*10) #10MB per writing chunk to avoid reading big file into memory. 

    Это именно то, что fileinput для:

     import fileinput with open(outfilename, 'w') as fout, fileinput.input(filenames) as fin: for line in fin: fout.write(line) 

    Для этого варианта использования это действительно не намного проще, чем просто перебирать файлы вручную, но в других случаях очень удобно иметь один итератор, который выполняет итерации по всем файлам, как если бы они были одним файлом. (Кроме того, тот факт, что fileinput закрывает каждый файл, как только это делается, означает, что нет необходимости в close или close каждого из них, но это всего лишь однострочная экономия, а не большая сделка.)

    В fileinput есть и другие отличные функции, такие как возможность делать модификации файлов на месте только путем фильтрации каждой строки.


    Как отмечается в комментариях, и обсуждается в другом сообщении , fileinput для Python 2.7 не будет работать, как указано. Здесь небольшая модификация, чтобы сделать код Python 2.7 совместимым

     with open('outfilename', 'w') as fout: fin = fileinput.input(filenames) for line in fin: fout.write(line) fin.close() 

    Что случилось с командами UNIX? (если вы не работаете в Windows):

    ls | xargs cat | tee output.txt ls | xargs cat | tee output.txt выполняет задание (вы можете вызвать его из python с помощью подпроцесса, если хотите)

    Я не знаю об элегантности, но это работает:

      import glob import os for f in glob.glob("file*.txt"): os.system("cat "+f+" >> OutFile.txt") 

    Проверьте метод .read () объекта File:

    http://docs.python.org/2/tutorial/inputoutput.html#methods-of-file-objects

    Вы могли бы сделать что-то вроде:

     concat = "" for file in files: concat += open(file).read() 

    или более «элегантный» python-way:

     concat = ''.join([open(f).read() for f in files]) 

    который, согласно этой статье: http://www.skymind.com/~ocrow/python_string/ также будет самым быстрым.

    Если файлы не являются гигантскими:

     with open('newfile.txt','wb') as newf: for filename in list_of_files: with open(filename,'rb') as hf: newf.write(hf.read()) # newf.write('\n\n\n') if you want to introduce # some blank lines between the contents of the copied files 

    Если файлы слишком велики, чтобы их можно было полностью читать и хранить в ОЗУ, алгоритм должен быть немного отличающимся от чтения каждого файла, который должен быть скопирован в цикле кусками фиксированной длины, например, с использованием read(10000) .

     def concatFiles(): path = 'input/' files = os.listdir(path) for idx, infile in enumerate(files): print ("File #" + str(idx) + " " + infile) concat = ''.join([open(path + f).read() for f in files]) with open("output_concatFile.txt", "w") as fo: fo.write(path + concat) if __name__ == "__main__": concatFiles() 

    Альтернатива ответу @ inspectorG4dget (лучший ответ на сегодняшний день 29-03-2016). Я тестировал 3 файла из 436 МБ.

    Решение @ inspectorG4dget: 162 секунды

    Следующее решение: 125 секунд

     from subprocess import Popen filenames = ['file1.txt', 'file2.txt', 'file3.txt'] fbatch = open('batch.bat','w') str ="type " for f in filenames: str+= f + " " fbatch.write(str + " > file4results.txt") fbatch.close() p = Popen("batch.bat", cwd=r"Drive:\Path\to\folder") stdout, stderr = p.communicate() 

    Идея состоит в том, чтобы создать пакетный файл и выполнить его, воспользовавшись «старыми хорошими технологиями». Его полупиттон работает быстрее. Работает для окон.

    Если у вас много файлов в каталоге, то glob2 может быть лучшим вариантом для создания списка имен файлов, а не для записи их вручную.

     import glob2 filenames = glob2.glob('*.txt') # list of all .txt files in the directory with open('outfile.txt', 'w') as f: for file in filenames: with open(file) as infile: f.write(infile.read()+'\n') 
    Python - лучший язык программирования в мире.