Saya memiliki file yang sangat besar (~ 400 GB), dan saya harus menghapus 2 baris terakhir darinya. Saya mencoba menggunakan sed
, tetapi itu berjalan selama berjam-jam sebelum saya menyerah. Apakah ada cara cepat untuk melakukan ini, atau saya terjebak sed
?
linux
sed
text-manipulation
Russ Bradberry
sumber
sumber
head -n -2 file
Jawaban:
Saya belum mencoba ini pada file besar untuk melihat seberapa cepat itu, tetapi harus cukup cepat.
Untuk menggunakan skrip untuk menghapus baris dari akhir file:
Itu mencari ke akhir file, memeriksa untuk memastikan karakter terakhir adalah baris baru, kemudian membaca setiap karakter satu per satu akan mundur hingga ditemukan tiga baris baru dan memotong file tepat setelah titik itu. Perubahan dilakukan di tempat.
Sunting: Saya telah menambahkan versi Python 2.4 di bagian bawah.
Ini adalah versi untuk Python 2.5 / 2.6:
Ini versi Python 3:
Berikut adalah versi Python 2.4:
sumber
Anda dapat mencoba kepala GNU
sumber
head: illegal line count -- -2
Saya melihat sistem Squian / pengujian Debian saya (tetapi bukan Lenny / stable) menyertakan perintah "truncate" sebagai bagian dari paket "coreutils".
Dengan itu Anda bisa melakukan sesuatu seperti
untuk menghapus 160 byte dari akhir file (jelas Anda perlu mencari tahu persis berapa banyak karakter yang perlu Anda hapus).
sumber
dd
skrip sederhana akan melakukan itu (Anda perlu menentukan offset input untuk mendapatkan kilobyte terakhir dan kemudian menggunakantail -2 | LANG= wc -c
, atau sth seperti itu).tail
efisien untuk file besar, juga - dapat digunakantail | wc -c
untuk menghitung jumlah byte yang akan dipangkas.Masalah dengan sed adalah bahwa itu adalah editor aliran - itu akan memproses seluruh file bahkan jika Anda hanya ingin membuat modifikasi di akhir. Jadi, apa pun yang terjadi, Anda membuat file 400GB baru, baris demi baris. Editor apa pun yang beroperasi pada seluruh file mungkin akan mengalami masalah ini.
Jika Anda tahu jumlah garis, Anda bisa menggunakan
head
, tetapi sekali lagi ini membuat file baru alih-alih mengubah yang sudah ada di tempat. Anda mungkin mendapatkan keuntungan cepat dari kesederhanaan tindakan, saya kira.Anda mungkin lebih beruntung menggunakan
split
untuk memecah file menjadi potongan-potongan kecil, mengedit yang terakhir, dan kemudian menggunakancat
untuk menggabungkannya lagi, tapi saya tidak yakin apakah itu akan lebih baik. Saya akan menggunakan jumlah byte daripada garis, jika tidak, mungkin tidak akan lebih cepat sama sekali - Anda masih akan membuat file 400GB baru.sumber
Coba VIM ... Saya tidak yakin apakah ini akan berhasil atau tidak, karena saya belum pernah menggunakannya pada file sebesar itu, tapi saya sudah menggunakannya pada file yang lebih kecil sebelumnya, coba saja.
sumber
Jenis file apa dan dalam format apa? Mungkin lebih mudah untuk menggunakan sesuatu seperti Perl tergantung pada jenis file apa itu - teks, grafik, biner? Bagaimana cara diformat - CSV, TSV ...
sumber
Jika Anda tahu ukuran file ke byte (400000000160 katakan) dan Anda tahu bahwa Anda harus menghapus 160 karakter untuk menghapus dua baris terakhir, maka sesuatu seperti
harus melakukan trik. Sudah lama sejak saya menggunakan dd dalam kemarahan; Sepertinya saya ingat semuanya berjalan lebih cepat jika Anda menggunakan ukuran blok yang lebih besar, tetapi apakah Anda bisa melakukannya tergantung pada apakah garis yang ingin Anda turun berada pada kelipatan yang bagus.
dd memiliki beberapa opsi lain untuk menyalin catatan teks ke ukuran tetap yang mungkin berguna sebagai pass awal.
sumber
Jika perintah "truncate" tidak tersedia di sistem Anda (lihat jawaban saya yang lain), lihat "man 2 truncate" untuk panggilan sistem untuk memotong file hingga panjang tertentu.
Tentunya Anda perlu tahu berapa banyak karakter yang Anda butuhkan untuk memotong file (ukuran dikurangi panjang masalah dua baris; jangan lupa untuk menghitung karakter cr / lf).
Dan buat cadangan file sebelum Anda mencoba ini!
sumber
Jika Anda lebih suka solusi unix-style, Anda dapat menyimpan dan memotong garis interaktif menggunakan tiga baris kode (Diuji pada Mac dan Linux).
pemotongan garis kecil + aman unix-style (meminta konfirmasi):
Solusi ini bergantung pada beberapa unix-tools umum, tetapi masih digunakan
perl -e "truncate(file,length)"
sebagai pengganti terdekattruncate(1)
, yang tidak tersedia di semua sistem.Anda juga dapat menggunakan program shell komprehensif yang dapat digunakan kembali berikut ini, yang menyediakan info penggunaan dan konfirmasi pemotongan fitur, penguraian opsi, dan penanganan kesalahan.
skrip pemotongan garis komprehensif :
Ini adalah contoh penggunaan:
sumber
perubahan dilakukan di tempat. Ini lebih sederhana dan lebih efisien daripada skrip python.
sumber
ed
membutuhkan waktu 100 kali lebih lama untuk dieksekusi daripada skrip Python saya. Saya hanya bisa membayangkan berapa besar perbedaannya untuk file OP yang 7000 kali lebih besar.Memodifikasi jawaban yang diterima untuk memecahkan masalah serupa. Bisa di-tweak sedikit untuk menghapus n baris.
Dan tes yang sesuai:
sumber
Anda dapat menggunakan Vim dalam mode Ex:
-,
pilih 2 baris terakhird
menghapusx
Simpan dan tutupsumber