Dalam jawaban ini ( Bagaimana saya bisa menghapus baris pertama file dengan sed? ) Ada dua cara untuk menghapus catatan pertama dalam file:
sed '1d' $file >> headerless.txt
** ---------------- ATAU ----------------**
tail -n +2 $file >> headerless.txt
Secara pribadi saya pikir tail
pilihan secara kosmetik lebih menyenangkan dan lebih mudah dibaca tetapi mungkin karena saya tertantang.
Metode mana yang tercepat?
sed
lebih portabel: "+2" untuktail
berfungsi dengan baik di Ubuntu, yang menggunakan GNUtail
, tetapi tidak akan berfungsi pada BSDtail
.tail
kurangnya kompatibilitas lintas platform.-n
opsi, dan menggunakan sintaksistail +2 $file
. Lihat freebsd.org/cgi/… Mungkin Anda memikirkannya daripada salah satu BSD modern.Jawaban:
Kinerja
sed
vs.tail
untuk menghapus baris pertama fileTL; DR
sed
sangat kuat dan serbaguna, tetapi inilah yang membuatnya lambat, terutama untuk file besar dengan banyak baris.tail
tidak hanya satu hal sederhana, tetapi yang dilakukannya dengan baik dan cepat, bahkan untuk file yang lebih besar dengan banyak baris.Untuk file berukuran kecil dan menengah,
sed
dantail
berkinerja sama cepat (atau lambat, tergantung pada harapan Anda). Namun, untuk file input yang lebih besar (beberapa MB), perbedaan kinerja tumbuh secara signifikan (urutan besarnya untuk file dalam kisaran ratusan MB), dengantail
kinerja yang jelas lebih baiksed
.Percobaan
Persiapan Umum:
Perintah kami untuk menganalisis adalah:
Perhatikan bahwa saya mem-piping output ke
/dev/null
setiap kali untuk menghilangkan output terminal atau file menulis sebagai bottleneck kinerja.Mari kita mengatur disk RAM untuk menghilangkan disk I / O sebagai hambatan potensial. Saya pribadi sudah
tmpfs
memasang di/tmp
jadi saya hanya menempatkan saya ditestfile
sana untuk percobaan ini.Kemudian saya pernah membuat file uji acak yang berisi jumlah baris tertentu
$numoflines
dengan panjang garis acak dan data acak menggunakan perintah ini (perhatikan bahwa itu pasti tidak optimal, itu menjadi sangat lambat untuk sekitar> 2M baris, tetapi siapa yang peduli, itu bukan hal yang kami analisis):Oh, btw. laptop uji saya menjalankan Ubuntu 16.04, 64 bit pada CPU Intel i5-6200U. Hanya untuk perbandingan.
Mengatur waktu file besar:
Menyiapkan besar
testfile
:Menjalankan perintah di atas dengan
numoflines=10000000
menghasilkan file acak yang berisi 10M baris, menempati sedikit lebih dari 600 MB - ini cukup besar, tetapi mari kita mulai dengan itu, karena kita dapat:Lakukan lari berjangka waktu dengan besar kami
testfile
:Sekarang mari kita lakukan hanya menjalankan satu waktu dengan kedua perintah terlebih dahulu untuk memperkirakan dengan apa yang kita kerjakan.
Kami sudah melihat hasil yang sangat jelas untuk file besar,
tail
besarnya lebih cepat darised
. Tapi hanya untuk bersenang-senang dan untuk memastikan tidak ada efek samping acak yang membuat perbedaan besar, mari kita lakukan 100 kali:Kesimpulannya tetap sama,
sed
tidak efisien untuk menghapus baris pertama file besar,tail
harus digunakan di sana.Dan ya, saya tahu konstruksi loop Bash lambat, tapi kami hanya melakukan iterasi yang relatif sedikit di sini dan waktu yang dibutuhkan loop polos tidak signifikan dibandingkan dengan
sed
/tail
runtimes.Pengaturan waktu file kecil:
Menyiapkan kecil
testfile
:Sekarang untuk kelengkapan, mari kita lihat kasus yang lebih umum bahwa Anda memiliki file input kecil dalam kisaran kB. Mari kita buat file input acak dengan
numoflines=100
, tampak seperti ini:Lakukan lari waktunya dengan kecil kami
testfile
:Karena kita dapat mengharapkan pengaturan waktu untuk file kecil seperti itu berada dalam kisaran beberapa milidetik dari pengalaman, mari kita lakukan 1000 iterasi segera:
Seperti yang Anda lihat, waktunya sangat mirip, tidak ada banyak untuk menafsirkan atau bertanya-tanya. Untuk file kecil, kedua alat sama-sama cocok.
sumber
awk
dapat melakukan ini juga. Pertanyaan asli saya didasarkan pada tautan yang saya temukan di tempat pertama. Setelah semua kerja keras Anda, mohon saran jika saya harus menghapusawk
sebagai kandidat solusi dan kembali fokus ke lingkup proyek asli hanyased
dantail
.awk 'NR > 1'
, yang menarik).Berikut alternatif lain, hanya menggunakan bash builtins dan
cat
:$file
diarahkan ke{ }
pengelompokan perintah. Theread
hanya membaca dan membuang baris pertama. Sisa dari aliran ini kemudian disalurkan kecat
yang menuliskannya ke file tujuan.Di Ubuntu 16.04 saya, kinerja ini dan
tail
solusinya sangat mirip. Saya membuat file uji largish denganseq
:tail
larutan:cat
/ solusi brace:Saya hanya memiliki Ubuntu VM berguna sekarang, dan melihat variasi yang signifikan dalam pengaturan waktu dari keduanya, meskipun mereka semua di ballpark yang sama.
sumber
tail
tetapi masih berpikirread
opsi ini sangat keren.Mencoba di sistem saya, dan mengawali setiap perintah dengan
time
saya mendapat hasil berikut:sed:
dan ekor:
yang menyarankan bahwa, pada sistem saya setidaknya AMD FX 8250 yang menjalankan Ubuntu 16.04, tail secara signifikan lebih cepat. File tes memiliki 10.000 baris dengan ukuran 540k. File itu dibaca dari HDD.
sumber
sed
mungkin memainkan faktor dalam hasil ini, itulah urutan Anda mengujinya.sed
sekitar dua kali lebih cepat.Tidak ada cara obyektif untuk mengatakan mana yang lebih baik, karena
sed
dantail
bukan satu-satunya hal yang berjalan pada sistem selama eksekusi program. Banyak faktor seperti disk i / o, jaringan i / o, CPU menyela proses prioritas lebih tinggi - semua itu mempengaruhi seberapa cepat program Anda akan berjalan.Keduanya ditulis dalam bahasa C, jadi ini bukan masalah bahasa, tetapi lebih masalah lingkungan. Sebagai contoh, saya memiliki SSD dan pada sistem saya ini akan membutuhkan waktu dalam mikrodetik, tetapi untuk file yang sama pada hard drive akan membutuhkan lebih banyak waktu karena HDD secara signifikan lebih lambat. Jadi perangkat keras juga berperan dalam hal ini.
Ada beberapa hal yang mungkin perlu Anda ingat ketika mempertimbangkan perintah mana yang harus dipilih:
sed
adalah editor aliran untuk mengubah teks.tail
adalah untuk menghasilkan baris teks tertentu. Jika Anda ingin berurusan dengan garis dan hanya mencetaknya, gunakantail
. Jika Anda ingin mengedit teks, gunakansed
.tail
memiliki sintaks yang jauh lebih sederhana daripada itused
, jadi gunakan apa yang bisa Anda baca sendiri dan apa yang orang lain bisa baca.Faktor penting lainnya adalah jumlah data yang Anda proses. File kecil tidak akan memberi Anda perbedaan kinerja. Gambar menjadi menarik saat Anda berurusan dengan file besar. Dengan 2GB BIGFILE.txt, kita dapat melihat bahwa
sed
memiliki lebih banyak panggilan sistem daripadatail
, dan berjalan jauh lebih lambat.sumber
tail
lebih baik daripadased
- gunakan itu. Saya pribadi akan menggunakanpython
atauawk
bukansed
karena bisa rumit. Selain itu, jika Anda khawatir tentang kinerja, mari kita hadapi kenyataan - Anda melihat hasil dalam mikrodetik di sini. Anda tidak akan merasakan perbedaan kecuali itu file besar freakin dalam kisaran gigabyte yang ingin Anda bacaawk
jawaban:) ... Pertanyaan saya didasarkan pada T&J AU lain (di tautan) dan di sana mereka tidak pernah menyebutkanawk
. Saya setuju perbedaan waktu nominal pada file kecil. Saya hanya mencoba mengembangkan beberapa kebiasaan baik.awk 'NR!=1' input_file.txt
. Ini memberi saya hasil yang sama, sekitar 150 milidetik, jumlah yang sama untuk keduanyatail
dansed
. Tapi agian, saya menggunakan SSD, jadi saya akan mengatakan itu adalah hard drive dan CPU yang penting, bukan perintah.sed
waktu lebih dari 3 menit, sedangkantail
hanya membutuhkan sekitar 20 detik. Itu tidak terlalu besar namun sebenarnya, pasti tidak dalam kisaran GB.Jawaban teratas tidak memasukkan disk ke dalam akun
> /dev/null
jika Anda memiliki file besar dan tidak ingin membuat duplikat sementara pada disk Anda, cobalah
vim -c
Sunting: jika file lebih besar dari memori yang tersedia
vim -c
tidak berfungsi, sepertinya itu tidak cukup pintar untuk melakukan penambahan filesumber
Jawaban lain menunjukkan dengan baik apa yang lebih baik untuk membuat file baru dengan baris pertama hilang. Jika Anda ingin mengedit file daripada membuat file baru, saya yakin
ed
akan lebih cepat karena seharusnya tidak membuat file baru sama sekali. Tetapi Anda harus mencari cara menghapus garis denganed
karena saya hanya menggunakannya sekali.sumber