Saya memiliki daftar 20 nama file, seperti ['file1.txt', 'file2.txt', ...]
. Saya ingin menulis skrip Python untuk menggabungkan file-file ini menjadi file baru. Saya bisa membuka setiap file dengan f = open(...)
, membaca baris demi baris dengan menelepon f.readline()
, dan menulis setiap baris ke file baru itu. Rasanya tidak "elegan" bagi saya, terutama bagian di mana saya harus membaca // menulis baris demi baris.
Apakah ada cara yang lebih "elegan" untuk melakukan ini dengan Python?
python
file-io
concatenation
JJ Beck
sumber
sumber
cat file1.txt file2.txt file3.txt ... > output.txt
. Dengan python, jika Anda tidak sukareadline()
, selalu adareadlines()
atau sederhanaread()
.cat file1.txt file2.txt file3.txt
perintah menggunakansubprocess
modul dan Anda selesai. Tapi saya tidak yakin apakahcat
berfungsi di windows.with
pernyataan untuk memastikan file Anda ditutup dengan benar, dan beralihlah ke file untuk mendapatkan baris, daripada menggunakanf.readline()
.Jawaban:
Ini harus dilakukan
Untuk file besar:
Untuk file kecil:
… Dan satu lagi yang menarik yang saya pikirkan :
Sayangnya, metode terakhir ini menyisakan beberapa deskriptor file terbuka, yang harus dijaga oleh GC. Saya hanya berpikir itu menarik
sumber
Gunakan
shutil.copyfileobj
.Secara otomatis membaca file input potongan demi sepotong untuk Anda, yang lebih efisien dan membaca file input dan akan bekerja bahkan jika beberapa file input terlalu besar untuk masuk ke dalam memori:
sumber
for i in glob.glob(r'c:/Users/Desktop/folder/putty/*.txt'):
baik saya mengganti pernyataan untuk memasukkan semua file dalam direktori tetapi sayaoutput_file
mulai tumbuh sangat besar seperti di 100's of gb dalam waktu yang sangat cepat.Itulah yang fileinput adalah untuk:
Untuk kasus penggunaan ini, itu sebenarnya tidak jauh lebih sederhana daripada hanya iterasi file secara manual, tetapi dalam kasus lain, memiliki iterator tunggal yang melakukan iterasi pada semua file seolah-olah mereka adalah file tunggal sangat berguna. (Juga, fakta bahwa
fileinput
menutup setiap file segera setelah selesai berarti tidak perluwith
atauclose
masing - masing, tapi itu hanya penghematan satu baris, bukan masalah besar.)Ada beberapa fitur bagus lainnya
fileinput
, seperti kemampuan untuk melakukan modifikasi di tempat file hanya dengan memfilter setiap baris.Seperti disebutkan dalam komentar, dan dibahas dalam posting lain ,
fileinput
untuk Python 2.7 tidak akan berfungsi seperti yang ditunjukkan. Berikut sedikit modifikasi untuk membuat kode Python 2.7 sesuaisumber
fileinput
diberitahu bahwa ini adalah cara untuk mengubah yang sederhanasys.argv
(atau apa yang tersisa sebagai argumen setelahoptparse
/ dll.) Menjadi file virtual besar untuk skrip sepele, dan jangan berpikir untuk menggunakannya untuk apa pun lain (yaitu, ketika daftar bukan argumen baris perintah). Atau mereka memang belajar, tetapi kemudian lupa — saya terus menemukannya kembali setiap atau dua tahun sekali ...for line in fileinput.input()
bukan cara terbaik untuk memilih dalam kasus khusus ini: OP ingin menyatukan file, tidak membacanya baris demi baris yang secara teoritis merupakan proses yang lebih lama untuk dieksekusiSaya tidak tahu tentang keanggunan, tetapi ini bekerja:
sumber
cat
bisa mengambil daftar file, jadi tidak perlu berulang kali menyebutnya. Anda dapat dengan mudah membuatnya aman dengan meneleponsubprocess.check_call
alih-alihos.system
Apa yang salah dengan perintah UNIX? (mengingat Anda tidak bekerja di Windows):
ls | xargs cat | tee output.txt
melakukan pekerjaan (Anda dapat memanggilnya dari python dengan subprocess jika Anda mau)sumber
cat * | tee output.txt
.cat file1.txt file2.txt | tee output.txt
1> /dev/null
di akhir perintahTolok ukur sederhana menunjukkan bahwa shutil berkinerja lebih baik.
sumber
Alternatif jawaban @ inspectorG4dget (jawaban terbaik hingga tanggal 29-03-2016). Saya diuji dengan 3 file 436MB.
solusi @ inspectorG4dget: 162 detik
Solusi berikut: 125 detik
Idenya adalah untuk membuat file batch dan menjalankannya, mengambil keuntungan dari "teknologi lama yang baik". Semi-python tetapi bekerja lebih cepat. Bekerja untuk windows.
sumber
Jika Anda memiliki banyak file di direktori maka
glob2
mungkin merupakan opsi yang lebih baik untuk menghasilkan daftar nama file daripada menulisnya dengan tangan.sumber
Lihat metode .read () dari objek File:
http://docs.python.org/2/tutorial/inputoutput.html#methods-of-file-objects
Anda dapat melakukan sesuatu seperti:
atau cara python yang lebih 'elegan':
yang, menurut artikel ini: http://www.skymind.com/~ocrow/python_string/ juga akan menjadi yang tercepat.
sumber
Jika file tidak raksasa:
Jika file terlalu besar untuk sepenuhnya dibaca dan disimpan dalam RAM, algoritme harus sedikit berbeda untuk membaca setiap file yang akan disalin dalam satu lingkaran dengan potongan dengan panjang tetap, menggunakan
read(10000)
misalnya.sumber
os.open
danos.read
, karena plainopen
menggunakan pembungkus Python di sekitar stdio C, yang berarti 1 atau 2 buffer tambahan menghalangi Anda.sumber
sumber