Saya punya skenario di mana baris ditambahkan pada awal dan akhir file besar.
Saya sudah mencoba seperti yang ditunjukkan di bawah ini.
untuk baris pertama:
sed -i '1i\'"$FirstLine" $Filename
untuk baris terakhir:
sed -i '$ a\'"$Lastline" $Filename
Tetapi masalah dengan perintah ini adalah bahwa ia menambahkan baris pertama file dan melintasi seluruh file. Untuk baris terakhir itu lagi melintasi seluruh file dan menambahkan baris terakhir. Karena file yang sangat besar (14GB) ini membutuhkan waktu yang sangat lama.
Bagaimana saya bisa menambahkan baris ke awal dan yang lain ke akhir file sambil hanya membaca file sekali?
sumber
for
perulangan:for file in Tes*; do [command]; done
"$file"
, bukanTes*
sebagai argumened
.Perhatikan bahwa jika Anda ingin menghindari mengalokasikan seluruh salinan file pada disk, Anda dapat melakukan:
Itu menggunakan fakta bahwa ketika stdin / stdout adalah file,
sed
membaca dan menulis dengan blok. Jadi di sini,sed
boleh saja untuk mengganti file yang dibacanya selama baris pertama yang Anda tambahkan lebih kecil dari ukuran blok (harus sekitar 4k atau 8k).Perhatikan bahwa jika karena alasan tertentu
sed
gagal (terbunuh, kerusakan mesin ...), Anda akan berakhir dengan file setengah diproses yang berarti sejumlah data ukuran baris pertama hilang di suatu tempat di tengah.Perhatikan juga bahwa kecuali Anda
sed
adalah GNUsed
, itu tidak akan berfungsi untuk data biner (tetapi karena Anda menggunakan-i
, Anda menggunakan sed GNU).sumber
Berikut adalah beberapa pilihan (semuanya akan membuat salinan file baru jadi pastikan Anda memiliki cukup ruang untuk itu):
gema / kucing sederhana
awk / gawk dll
awk
dan sejenisnya membaca file baris demi baris. TheBEGIN{}
blok dijalankan sebelum baris pertama danEND{}
blok setelah baris terakhir. Jadi, perintah di atas berartiprint "first" at the beginning, then print every line in the file and print "last" at the end
.Perl
Ini pada dasarnya hal yang sama dengan gawk di atas yang baru saja ditulis dalam Perl.
sumber
sed -i
yang membuat file temp.Saya lebih suka yang lebih sederhana:
Ini mengubah file:
ke file:
sumber
Anda dapat menggunakan Vim dalam mode Ex:
1
pilih baris pertamai
masukkan teks dan baris baru$
pilih baris terakhira
tambahkan teks dan baris barux
Simpan dan tutupsumber
Tidak ada cara untuk memasukkan data di awal file¹, yang dapat Anda lakukan adalah membuat file baru, menulis data tambahan, dan menambahkan data lama. Jadi, Anda harus menulis ulang seluruh file setidaknya satu kali untuk memasukkan baris pertama. Anda dapat menambahkan baris terakhir tanpa menulis ulang file.
Atau, Anda dapat menggabungkan dua perintah dalam satu kali sed.
sed -i
membuat file output baru dan kemudian memindahkannya ke file lama. Ini berarti bahwa ketika sed sedang bekerja, ada salinan kedua file menggunakan ruang kosong. Anda dapat menghindari ini dengan menimpa file di tempat , tetapi dengan batasan besar: baris yang Anda tambahkan harus lebih kecil dari buffer sed, dan jika sistem Anda macet Anda akan berakhir dengan file yang rusak dan beberapa konten hilang di tengah, jadi saya sangat merekomendasikan untuk tidak melakukannya.¹ Linux memang memiliki cara untuk memasukkan data ke dalam file, tetapi ia hanya dapat menyisipkan sejumlah besar blok sistem file, ia tidak dapat memasukkan string dengan panjang sewenang-wenang. Ini berguna untuk beberapa aplikasi, seperti database dan mesin virtual, tetapi tidak berguna untuk file teks.
sumber
fallocate()
denganFALLOC_FL_INSERT_RANGE
tersedia di XFS dan ext4 di kernel modern (4.xx) man7.org/linux/man-pages/man2/fallocate.2.htmlsumber
Kernel Linux modern (lebih tinggi dari 4,1 atau 4,2) mendukung memasukkan data pada awal file melalui
fallocate()
system call denganFALLOC_FL_INSERT_RANGE
pada sistem file ext4 dan xfs. Pada dasarnya ini adalah operasi pemindahan logis: data secara logis dipindahkan pada offset yang lebih tinggi.Ada kendala terkait granularity dari rentang yang ingin Anda masukkan di awal file. Tetapi untuk file teks Anda mungkin dapat mengalokasikan sedikit lebih dari yang dibutuhkan (hingga batas granularity) dan mengisi dengan spasi atau carriage return, tetapi itu tergantung pada aplikasi Anda
Saya tidak tahu ada utilitas linux yang tersedia yang memanipulasi luasan file tetapi tidak sulit untuk menulis: dapatkan deskriptor file dan panggil
fallocate()
dengan argumen yang sesuai. Untuk perincian lebih lanjut, lihat halaman manual darifallocate
panggilan sistem: http://man7.org/linux/man-pages/man2/fallocate.2.htmlsumber
fallocate
utilitas. Masalahnya adalah bahwa rincian seluruh blok membuat ini tidak berguna untuk sebagian besar file teks. Masalah lain adalah bahwa alokasi rentang dan modifikasi selanjutnya bukan atom. Jadi ini sebenarnya tidak menyelesaikan masalah di sini.fallocate
atomicity rusak tolong, saya ingin tahu)