Jawaban:
Coba ed
sebagai gantinya:
ed <<< $'1d\nwq' large_file
Jika "besar" itu berarti sekitar 10 juta baris atau lebih, lebih baik digunakan tail
. Tidak dapat mengedit di tempat, tetapi kinerjanya membuat kekurangan itu dapat dimaafkan:
tail -n +2 large_file > large_file.new
Edit untuk menunjukkan beberapa perbedaan waktu:
( awk
kode oleh Jaypal ditambahkan untuk memiliki waktu eksekusi pada mesin yang sama (CPU 2.2GHz).)
bash-4.2$ seq 1000000 > bigfile.txt # further file creations skipped
bash-4.2$ time sed -i 1d bigfile.txt
time 0m4.318s
bash-4.2$ time ed -s <<< $'1d\nwq' bigfile.txt
time 0m0.533s
bash-4.2$ time perl -pi -e 'undef$_ if$.==1' bigfile.txt
time 0m0.626s
bash-4.2$ time { tail -n +2 bigfile.txt > bigfile.new && mv -f bigfile.new bigfile.txt; }
time 0m0.034s
bash-4.2$ time { awk 'NR>1 {print}' bigfile.txt > newfile.txt && mv -f newfile.txt bigfile.txt; }
time 0m0.328s
awk
dan mendapatkan hasil berikut -[jaypal:~/Temp] seq 1000000 > bigfile.txt [jaypal:~/Temp] time awk 'NR>1 {print}' bigfile.txt >newfile.txt real 0m0.649s user 0m0.601s sys 0m0.033s
awk
kinerja lebih dekat sed
. (Catatan untuk diri saya sendiri: jangan pernah mengharapkan - sebagai gantinya.)
tail -n +2 bigfile.txt > bigfile.new && mv -f bigfile.new bigfile.txt;
Saya menggunakan satu file dengan kunci untuk melacak daftar tugas tunggal yang digunakan oleh banyak proses. Saya mulai dengan apa poster awal yang digunakan: sed -i 1d large_file
. Itu menyebabkan file terkunci selama 1-2 detik. The tail/mv
combo melengkapi hampir seketika. Terima kasih!
Tidak ada cara untuk secara efisien menghapus sesuatu dari awal file. Menghapus data dari awal memerlukan penulisan ulang seluruh file.
Memotong dari ujung file bisa sangat cepat (OS hanya harus menyesuaikan informasi ukuran file, mungkin membersihkan blok yang sekarang tidak digunakan). Ini umumnya tidak mungkin ketika Anda mencoba untuk menghapus dari kepala file.
Secara teori ini bisa menjadi "cepat" jika Anda menghapus seluruh blok / luas tepat, tetapi tidak ada panggilan sistem untuk itu, jadi Anda harus mengandalkan semantik khusus sistem berkas (jika ada). (Atau memiliki beberapa bentuk offset di dalam blok / batas pertama untuk menandai awal sebenarnya file, saya kira. Tidak pernah mendengarnya juga.)
Metode yang paling efisien, jangan lakukan itu! Jika Anda melakukannya, Anda perlu dua kali ruang 'besar' pada disk, dan Anda membuang IO.
Jika Anda terjebak dengan file besar yang ingin Anda baca tanpa baris 1, tunggu sampai Anda perlu membacanya untuk menghapus baris 1. Jika Anda perlu mengirim file dari stdin ke suatu program, gunakan tail untuk melakukannya:
tail -n +2 | your_program
Saat Anda perlu membaca file, Anda dapat mengambil kesempatan untuk menghapus baris 1, tetapi hanya jika Anda memiliki ruang yang dibutuhkan pada disk:
tail -n +2 | tee large_file2 | your_program
Jika Anda tidak dapat membaca dari stdin, gunakan fifo:
mkfifo large_file_wo_1st_line
tail -n +2 large_file > large_file_wo_1st_line&
your_program -i large_file_wo_1st_line
yang lebih baik lagi jika Anda menggunakan bash, manfaatkan penggantian proses:
your_program -i <(tail -n +2 large_file)
Jika Anda perlu mencari dalam file, saya tidak melihat solusi yang lebih baik daripada tidak terjebak dengan file di tempat pertama. Jika file ini dihasilkan oleh stdout:
large_file_generator | tail -n +2 > large_file
Selain itu, selalu ada solusi pengganti fifo atau proses:
mkfifo large_file_with_1st_file
large_file_generator -o large_file_with_1st_file&
tail -n +2 large_file_with_1st_file > large_file_wo_1st_file
large_file_generator -o >(tail -n 2+ > large_file_wo_1st_file)
Anda dapat menggunakan Vim dalam mode Ex:
ex -sc '1d|x' large_file
1
pilih baris pertama
d
menghapus
x
Simpan dan tutup
Ini hanya berteori, tapi ...
Sistem file khusus (diimplementasikan menggunakan FUSE atau mekanisme serupa) dapat mengekspos direktori yang isinya persis sama dengan direktori yang sudah ada di tempat lain, tetapi dengan file terpotong sesuai keinginan. Sistem file akan menerjemahkan semua offset file. Maka Anda tidak perlu melakukan penulisan ulang file yang memakan waktu.
Tetapi mengingat ide ini sangat tidak sepele, kecuali Anda punya puluhan terabyte file seperti itu, menerapkan sistem file seperti itu akan terlalu mahal / memakan waktu untuk menjadi praktis.
tail
, saya lebih suka menghitung waktu untuk melakukan keduanya menghapus baris pertama dan gantibigfile.txt
denganbigfile.new
.