У меня есть список из 20 имен файлов, например ['file1.txt', 'file2.txt', ...]
. Я хочу написать скрипт Python для объединения этих файлов в новый файл. Я мог бы открыть каждый файл f = open(...)
, прочитать строку за строкой, позвонив f.readline()
, и записать каждую строку в этот новый файл. Это не кажется мне очень «элегантным», особенно та часть, где я должен читать // писать построчно.
Есть ли более «элегантный» способ сделать это в Python?
python
file-io
concatenation
Джей Джей Бек
источник
источник
cat file1.txt file2.txt file3.txt ... > output.txt
. В питоне, если вам не нравитсяreadline()
, всегда естьreadlines()
или простоread()
.cat file1.txt file2.txt file3.txt
команду, используяsubprocess
модуль, и все готово. Но я не уверен,cat
работает ли в Windows.with
оператор, чтобы убедиться, что ваши файлы закрыты должным образом, и выполняйте итерации по файлу, чтобы получить строки, а не используйтеf.readline()
.Ответы:
Это должно сделать это
Для больших файлов:
Для небольших файлов:
... и еще один интересный, о котором я подумал :
К сожалению, этот последний метод оставляет несколько открытых файловых дескрипторов, которые GC должен позаботиться в любом случае. Я просто подумал, что это интересно
источник
Использование
shutil.copyfileobj
.Он автоматически считывает входные файлы по частям для вас, что более эффективно и считывает входные файлы и будет работать, даже если некоторые из входных файлов слишком велики для размещения в памяти:
источник
for i in glob.glob(r'c:/Users/Desktop/folder/putty/*.txt'):
хорошо, я заменил оператор for, чтобы включить все файлы в каталог, но мойoutput_file
рост стал действительно огромным, как в сотнях гб за очень короткое времяЭто именно то, для чего используется fileinput :
В этом случае это на самом деле не намного проще, чем просто выполнять итерации по файлам вручную, но в других случаях очень удобно иметь один итератор, который итерирует по всем файлам, как если бы они были одним файлом. (Кроме того, тот факт, что
fileinput
каждый файл закрывается сразу после его завершения, означает, что в этом нет необходимостиwith
илиclose
каждый из них, но это всего лишь экономия в одну строку, а не такая уж большая проблема.)Есть и другие отличные функции
fileinput
, такие как возможность вносить изменения в файлы, просто фильтруя каждую строку.Как отмечено в комментариях и обсуждено в другом посте ,
fileinput
для Python 2.7 не будет работать, как указано. Здесь небольшое изменение, чтобы сделать код Python 2.7 совместимымисточник
fileinput
этом, говорят, что это способ превратить простойsys.argv
(или то, что осталось в качестве аргументов послеoptparse
/ и т. иначе (то есть, когда список не является аргументами командной строки). Или они действительно учатся, но потом забывают - я продолжаю открывать это каждый год или два…for line in fileinput.input()
это не лучший способ выбора в данном конкретном случае: ОП хочет объединять файлы, а не читать их построчно, что теоретически более длительный процесс для выполненияЯ не знаю об элегантности, но это работает:
источник
cat
можно взять список файлов, поэтому нет необходимости повторно вызывать его. Вы можете легко сделать это безопасным, позвонивsubprocess.check_call
вместоos.system
Что не так с командами UNIX? (учитывая, что вы не работаете в Windows):
ls | xargs cat | tee output.txt
делает работу (вы можете вызвать его из python с подпроцессом, если хотите)источник
cat * | tee output.txt
.cat file1.txt file2.txt | tee output.txt
1> /dev/null
в конец командыПростой тест показывает, что шутил работает лучше.
источник
Альтернатива ответу @ inspectorG4dget (лучший ответ на сегодняшний день 29-03-2016). Я тестировал с 3 файлами 436MB.
Решение @ inspectorG4dget: 162 секунды
Следующее решение: 125 секунд
Идея состоит в том, чтобы создать пакетный файл и выполнить его, используя преимущества «старой доброй технологии». Его полупитон, но работает быстрее. Работает для окон.
источник
Если у вас много файлов в каталоге, то
glob2
может быть лучше создать список имен файлов, чем писать их вручную.источник
Проверьте метод .read () объекта File:
http://docs.python.org/2/tutorial/inputoutput.html#methods-of-file-objects
Вы могли бы сделать что-то вроде:
или более «элегантный» путь Python:
который, согласно этой статье: http://www.skymind.com/~ocrow/python_string/ также будет самым быстрым.
источник
Если файлы не гигантские:
Если файлы слишком велики, чтобы их можно было целиком прочитать и хранить в оперативной памяти, алгоритм должен немного отличаться, чтобы каждый файл, который будет скопирован в цикле, был прочитан фрагментами фиксированной длины,
read(10000)
например , с помощью .источник
os.open
иos.read
, поскольку plainopen
использует обертки Python вокруг stdio C, что означает, что на вашем пути встанет 1 или 2 дополнительных буфера.источник
источник