Jawaban:
Dengan sed, seperti:
sed '20,37d; 45d' < input.txt > output.txt
Jika Anda ingin melakukan ini di tempat:
sed --in-place '20,37d; 45d' file.txt
This option specifies that files are to be edited in-place. GNU sed 'melakukan ini dengan membuat file sementara dan mengirim output ke file ini daripada ke output standar. `... Saya tidak tahu tentang 'sed' lain selain logistik memperbarui" di tempat "dengan editor aliran jangan" menghitung ":)
Jika file tersebut cocok dengan nyaman dalam memori, Anda juga bisa menggunakan ed.
Perintahnya sangat mirip dengan yang di sedatas dengan satu perbedaan penting : Anda harus melewati daftar nomor / rentang baris yang akan dihapus dalam urutan menurun (dari baris tertinggi / rentang ke terendah). Alasannya adalah bahwa ketika Anda menghapus / menyisipkan / membagi / bergabung dengan baris ed, buffer teks diperbarui setelah setiap sub-perintah sehingga jika Anda menghapus beberapa baris, sisa baris berikut tidak lagi berada pada posisi yang sama di buffer ketika subcommand berikutnya dijalankan. Jadi, Anda harus mulai mundur 1 . Pengeditan di
tempat :
ed -s in_file <<IN
45d
20,37d
w
q
IN
atau
ed -s in_file <<< $'45d\n20,37d\nw\nq\n'
atau
printf '%s\n' 45d 20,37d w q | ed -s in_file
Ganti writus dengan ,printisan jika Anda ingin mencetak hasil yang dihasilkan alih-alih menulis ke file. Jika Anda ingin menjaga file asli tetap utuh dan menulis ke file lain, Anda dapat meneruskan nama file baru ke wsub- perintah rite:
ed -s in_file <<IN
78,86d
65d
51d
20,37d
w out_file
q
IN
1
Kecuali Anda bersedia menghitung nomor baris baru setelah setiap delete, yang cukup sepele untuk kasus khusus ini (setelah menghapus baris 20-37, yaitu 18 baris, baris 45 menjadi baris 27) sehingga Anda dapat menjalankan:
ed -s in_file <<IN
20,37d
27d
w
q
IN
Namun, jika Anda harus menghapus beberapa nomor / rentang baris, bekerja mundur adalah no-brainer.
qperintah itu berguna pada akhirnya? Saya kira itu keluar baik cara.
Cukup baca ke memori, ubah, lalu tulis kembali. Anda dapat melakukan sesuatu seperti
filename = "foo"
f = open(filename, 'r+')
linenums = [1, 3]
s = [y for x, y in enumerate(f) if x not in [line-1 for line in linenums]]
f.seek(0)
f.write(''.join(s))
f.truncate(f.tell())
f.close()
Diuji dengan file 5 baris. Kredit untuk http://pleac.sourceforge.net/pleac_python/fileaccess.html , lihat bagian "Memodifikasi File di Tempat Tanpa File Sementara". Lihat juga /programming/125703/how-do-i-modify-a-text-file-in-python
Beberapa catatan:
Pertama-tama orang dapat memotong file, kemudian menulis padanya, daripada menulis, kemudian memotong, seperti di atas. Namun, saya tidak tahu tentang bendera Python yang memungkinkan seseorang untuk membaca, dan kemudian melakukan penulisan terpotong. Tapi mungkin saya kehilangan sesuatu, karena dokumennya tidak begitu jelas. Yang membawaku ke
Terkadang dokumen Python benar-benar payah. Lihat http://docs.python.org/library/functions.html#open
Mode 'r +', 'w +' dan 'a +' membuka file untuk memperbarui (perhatikan bahwa 'w +' memotong file).
Apakah ini ada artinya bagi Anda? Apa itu "terbuka untuk memperbarui"?
Saya tidak tahu apakah melakukan ini dengan python sebagai lawan sesuatu yang aneh seperti editor aliran lebih baik. Mungkin lebih portabel, tapi saya tidak tahu seberapa sed portabel. Saya hanya menulis seperti itu karena saya lebih nyaman dengan pemrograman tingkat rendah daripada menggunakan alat unix klasik, yang bagus jika mereka melakukan apa yang Anda inginkan, tetapi (saya pikir) umumnya kurang fleksibel.
Pendekatan ini (memanipulasi file dalam memori) memperdagangkan memori untuk ruang disk. Seharusnya berfungsi pada mesin dengan beberapa Gb memori untuk file hingga beberapa ratus Mb. Python tidak menangani string dengan sangat efisien, jadi beralih ke C / C ++ misalnya akan sedikit meningkatkan kinerja dan sangat mengurangi penggunaan memori.
Anda dapat menggunakan Vim dalam mode Ex:
ex -sc '20,37d|45d|x' file
d menghapus
x Simpan dan tutup