Yanıtlar:
ed
Bunun yerine deneyin :
ed <<< $'1d\nwq' large_file
Bu “büyük” yaklaşık 10 milyon satır veya daha fazla anlamına gelirse, daha iyi kullanım tail
. Yerinde düzenleme yapamaz, ancak performansı bu affedilmez hale getirir:
tail -n +2 large_file > large_file.new
Düzen bir süre farklılıkları göstermek için:
( awk
Jaypal kodu aynı makinede yürütme süresine sahip olmak için eklendi (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
ve şu sonucu aldım -[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
performansının yakın olması bekleniyor sed
. (Kendime not: Asla beklemeyin - test
tail -n +2 bigfile.txt > bigfile.new && mv -f bigfile.new bigfile.txt;
Birden fazla işlem tarafından kullanılan tek bir görev listesini takip etmek için kilitli tek bir dosya kullanıyorum. Ben ilk afiş eskiden ne ile başladı: sed -i 1d large_file
. Dosyanın 1-2 saniye boyunca kilitlenmesine neden oluyordu. tail/mv
Açılan neredeyse anında tamamlar. Teşekkür ederim!
Bir dosyanın başındaki şeyleri etkin bir şekilde kaldırmanın bir yolu yoktur. Verilerin baştan kaldırılması tüm dosyanın yeniden yazılmasını gerektirir.
Bir dosyanın sonundan kesmek çok hızlı olabilir (işletim sistemi artık yalnızca kullanılmamış blokları temizleyerek dosya boyutu bilgisini ayarlamalıdır). Bir dosyanın başından kaldırmaya çalıştığınızda bu genellikle mümkün değildir.
Tam olarak bir bloğu / kapsamı kaldırırsanız teorik olarak "hızlı" olabilir, ancak bunun için sistem çağrıları yoktur, bu nedenle dosya sistemine özgü anlambilimden (varsa) güvenmeniz gerekir. (Ya da dosyanın ilk başlangıcını işaretlemek için birinci blok / kapsam dahilinde bir çeşit mahsuplaşma, sanırım. Bunu da hiç duymadım.)
En verimli yöntem, yapma! Bunu yaparsanız, herhangi bir durumda, diskte iki 'büyük' alana ihtiyacınız vardır ve IO'ları boşa harcarsınız.
İlk satır olmadan okumak istediğiniz büyük bir dosyaya sıkışmışsanız, ilk satırın kaldırılması için okumanız gerekene kadar bekleyin. Dosyayı stdin'den bir programa göndermeniz gerekirse, bunu yapmak için kuyruk kullanın:
tail -n +2 | your_program
Dosyayı okumanız gerektiğinde, 1. satırı kaldırma olanağınız olabilir, ancak yalnızca diskte gereken boş alan varsa:
tail -n +2 | tee large_file2 | your_program
Stdin'den okuyamıyorsanız, bir fifo kullanın:
mkfifo large_file_wo_1st_line
tail -n +2 large_file > large_file_wo_1st_line&
your_program -i large_file_wo_1st_line
bash kullanıyorsanız, işlem değişikliğinden yararlanın:
your_program -i <(tail -n +2 large_file)
Dosyada arama yapmanız gerekiyorsa, ilk başta dosyaya takılmamaktan daha iyi bir çözüm göremiyorum. Bu dosya stdout tarafından oluşturulmuşsa:
large_file_generator | tail -n +2 > large_file
Aksi halde, her zaman fifo veya proses ikame çözümü vardır:
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)
Vim'i Ex modunda kullanabilirsiniz:
ex -sc '1d|x' large_file
1
ilk satırı seç
d
silmek
x
kaydet ve kapat
Bu sadece teori, ama ...
Özel bir dosya sistemi (FUSE veya benzeri bir mekanizma kullanılarak uygulanır), içeriği zaten başka bir yerde var olan bir dizinin aynısı, ancak istediğiniz gibi kesilmiş dosyaların bulunduğu bir dizini gösterebilir. Dosya sistemi tüm dosya ofsetlerini tercüme eder. Öyleyse, bir dosyanın zaman alıcı bir kısmını yeniden yazmanız gerekmez.
Ancak, bu fikrin önemsiz olmadığı göz önüne alındığında, bu tür dosyalardan onlarca terabaytınız olmadıkça, bu tür bir dosya sistemini uygulamak pratik olamayacak kadar pahalı / zaman alıcı olacaktır.
tail
, oldukça yapmak için zaman saymaya kalksanız hem ilk satırı kaldırmak ve yerinebigfile.txt
sahipbigfile.new
.