Odpowiedzi:
Spróbuj ed
zamiast tego:
ed <<< $'1d\nwq' large_file
Jeśli ta „duża” oznacza około 10 milionów linii lub więcej, lepiej użyć tail
. Nie jest w stanie edytować w miejscu, ale jego wydajność sprawia, że brakowi można wybaczyć:
tail -n +2 large_file > large_file.new
Edytuj, aby pokazać różnice czasowe:
( awk
kod dodany przez Jaypal, aby mieć czasy wykonania na tym samym komputerze (procesor 2,2 GHz).)
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
i otrzymałem następujący wynik[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
, że występ będzie bliższy sed
. (Uwaga dla siebie: nigdy nie oczekuj - przetestuj zamiast tego)
tail -n +2 bigfile.txt > bigfile.new && mv -f bigfile.new bigfile.txt;
używam jednego pliku z blokadą do śledzenia pojedynczej listy zadań wykorzystywanej przez wiele procesów. Zacząłem co początkowy plakat wykorzystane: sed -i 1d large_file
. Powodowało to blokowanie pliku na 1-2 sekundy. tail/mv
Kombi kończy niemal natychmiast. Dziękuję Ci!
Nie ma sposobu, aby skutecznie usunąć rzeczy z początku pliku. Usuwanie danych od początku wymaga ponownego zapisania całego pliku.
Obcinanie od końca pliku może być jednak bardzo szybkie (system operacyjny musi tylko dostosować informacje o rozmiarze pliku, ewentualnie usuwając nieużywane teraz bloki). Zasadniczo nie jest to możliwe, gdy próbujesz usunąć z nagłówka pliku.
Teoretycznie może być „szybki”, jeśli dokładnie usuniesz cały blok / zakres, ale nie ma do tego żadnych wywołań systemowych, więc będziesz musiał polegać na specyficznej dla systemu plików semantyce (jeśli taka istnieje). (Albo mam jakąś formę przesunięcia w pierwszym bloku / zasięgu, aby zaznaczyć prawdziwy początek pliku, chyba. Nigdy o tym nie słyszałem.)
Najbardziej wydajna metoda, nie rób tego! Jeśli tak, to w każdym razie potrzebujesz dwa razy więcej „dużego” miejsca na dysku i marnujesz operacje wejścia / wyjścia.
Jeśli utknąłeś z dużym plikiem, który chcesz odczytać bez pierwszej linii, poczekaj, aż będziesz musiał go przeczytać w celu usunięcia pierwszej linii. Jeśli chcesz wysłać plik ze standardowego programu do programu, użyj tail, aby to zrobić:
tail -n +2 | your_program
Gdy potrzebujesz odczytać plik, możesz skorzystać z okazji, aby usunąć pierwszą linię, ale tylko jeśli masz potrzebne miejsce na dysku:
tail -n +2 | tee large_file2 | your_program
Jeśli nie możesz czytać ze standardowego wejścia, użyj 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
jeszcze lepiej, jeśli używasz bash, skorzystaj z substytucji procesu:
your_program -i <(tail -n +2 large_file)
Jeśli potrzebujesz szukać w pliku, nie widzę lepszego rozwiązania niż nie utknięcie w pliku. Jeśli ten plik został wygenerowany przez stdout:
large_file_generator | tail -n +2 > large_file
W przeciwnym razie zawsze istnieje rozwiązanie FIFO lub proces zastępowania procesów:
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)
Możesz używać Vima w trybie Ex:
ex -sc '1d|x' large_file
1
wybierz pierwszą linię
d
kasować
x
Zapisz i zamknij
To tylko teoria, ale ...
Niestandardowy system plików (zaimplementowany za pomocą FUSE lub podobnego mechanizmu) może ujawnić katalog, którego zawartość jest dokładnie taka sama, jak już istniejący katalog gdzie indziej, ale z plikami obciętymi, jak chcesz. System plików przetłumaczy wszystkie przesunięcia plików. W takim przypadku nie trzeba wykonywać czasochłonnego przepisywania pliku.
Ale biorąc pod uwagę, że ten pomysł jest bardzo trywialny, chyba że masz dziesiątki terabajtów takich plików, wdrożenie takiego systemu plików byłoby zbyt drogie / czasochłonne, aby było praktyczne.
tail
wolę liczyć czas zarówno na usunięcie pierwszego wiersza, jak i zastąpieniebigfile.txt
gobigfile.new
.