sed
Podejście jest w porządku, ale do pętli na wszystkich liniach nie jest. Jeśli wiesz, ile wierszy chcesz zachować (aby mieć przykład, używam tutaj 99), możesz to zrobić w następujący sposób:
sed -i '100,$ d' myfile.txt
Objaśnienie: sed
jest procesorem wyrażeń regularnych. Z -i
podaną opcją przetwarza plik bezpośrednio („inline”) - zamiast po prostu czytać go i zapisywać wyniki na standardowym wyjściu. 100,$
oznacza po prostu „od wiersza 100 do końca pliku” - po nim następuje polecenie d
, które prawdopodobnie poprawnie odgadłeś jako „usuń”. Krótko mówiąc, polecenie oznacza: „Usuń wszystkie linie z linii 100 do końca pliku z mojego pliku.txt”. 100 to pierwszy wiersz do usunięcia, ponieważ chcesz zachować 99 wierszy.
Edycja: Jeśli z drugiej strony istnieją pliki dziennika, w których chcesz zachować, np. Ostatnie 100 wierszy:
[ $(wc -l myfile.txt) -gt 100 ] && sed -i "1,$(($(wc -l myfile.txt|awk '{print $1}') - 100)) d" myfile.txt
Co tu się dzieje:
[ $(wc -l myfile.txt) -gt 100 ]
: wykonaj następujące czynności tylko wtedy, gdy plik ma więcej niż 100 linii
$((100 - $(wc -l myfile.txt|awk '{print $1}')))
: oblicz liczbę linii do usunięcia (tzn. wszystkie linie pliku oprócz (ostatnich) 100 do zachowania)
1, $((..)) d
: usuń wszystkie linie od pierwszej do linii obliczonej
EDYCJA: ponieważ pytanie zostało właśnie zredagowane, aby podać więcej szczegółów, do mojej odpowiedzi dołączę również te dodatkowe informacje. Dodano fakty:
- plik ma określony rozmiar (10 000 bajtów)
- każda linia ma określony rozmiar w bajtach (300 bajtów w przykładzie)
Na podstawie tych danych można obliczyć liczbę linii, które pozostaną jako „/”, co w przykładzie oznaczałoby 33 linie. Termin powłoki do obliczeń: $((size_to_remain / linesize))
(przynajmniej w systemie Linux przy użyciu Bash, wynikiem jest liczba całkowita). Skorygowane polecenie brzmiałoby teraz:
# keep the start of the file (OPs question)
sed -i '34,$ d' myfile.txt
# keep the end of the file (my second example)
[ $(wc -l myfile.txt) -gt 33 ] && sed -i "1,33 d" myfile.txt
Ponieważ rozmiary są znane z góry, nie ma już potrzeby wykonywania obliczeń osadzonych w sed
poleceniu. Ale dla elastyczności w skrypcie powłoki można używać zmiennych.
Do przetwarzania warunkowego opartego na rozmiarze pliku można użyć następującej „testowej” konstrukcji:
[ "$(ls -lk $file | awk ' {print $5}')" -gt 100 ] &&
co oznacza: „jeśli rozmiar $file
przekracza 100 ls -lk
kB , wykonaj ...” ( wyświetla rozmiar pliku w kB w pozycji 5, stąd awk
jest używany do wyodrębnienia dokładnie tego).