Odpowiedzi:
Możesz użyć tego do rozebrania pierwszych dwóch linii:
tail -n +3 foo.txt
i to, aby usunąć dwie ostatnie linie:
head -n -2 foo.txt
(zakładając, że plik kończy się \n
na drugim)
Podobnie jak w przypadku standardowego użycia tail
i head
te operacje nie są destrukcyjne. Użyj, >out.txt
jeśli chcesz przekierować dane wyjściowe do nowego pliku:
tail -n +3 foo.txt >out.txt
W przypadku, gdy out.txt
już istnieje, zastąpi ten plik. Użyj >>out.txt
zamiast, >out.txt
jeśli wolisz, aby wynik był dołączony out.txt
.
head -n -2
nie jest kompatybilny z POSIX .
Jeśli chcesz mieć wszystkie oprócz pierwszych linii N-1, zadzwoń tail
z liczbą linii +N
. (Liczba jest numerem pierwszego wiersza, który chcesz zachować, zaczynając od 1, tzn. +1 oznacza początek na górze, +2 oznacza pominięcie jednej linii i tak dalej).
tail -n +3 foo.txt >>other-document
Nie ma łatwego, przenośnego sposobu na pominięcie ostatnich N linii. GNU head
pozwala head -n +N
jako odpowiednik tail -n +N
. W przeciwnym razie, jeśli masz tac
(np. GNU lub Busybox), możesz połączyć go z tailem:
tac | tail -n +3 | tac
Przenośnie możesz użyć filtra awk (niesprawdzony):
awk -vskip=2 '{
lines[NR] = $0;
if (NR > skip) print lines[NR-skip];
delete lines[NR-skip];
}'
Jeśli chcesz usunąć kilka ostatnich wierszy z dużego pliku, możesz określić przesunięcie bajtu kawałka do obcięcia, a następnie wykonać obcięcie za pomocą dd
.
total=$(wc -c < /file/to/truncate)
chop=$(tail -n 42 /file/to/truncate | wc -c)
dd if=/dev/null of=/file/to/truncate seek=1 bs="$((total-chop))"
Na początku nie można obciąć pliku, ale jeśli chcesz usunąć kilka pierwszych wierszy dużego pliku, możesz przenosić zawartość .
Ze strony podręcznika tail
(czyli GNU tail
):
-n, --lines=K
output the last K lines, instead of the last 10; or use -n +K to
output lines starting with the Kth
Dlatego poniższe powinny dołączyć wszystkie oprócz pierwszych 2 wierszy somefile.txt
do anotherfile.txt
:
tail --lines=+3 somefile.txt >> anotherfile.txt
Aby usunąć pierwsze n wierszy, można użyć GNU sed. Na przykład, jeśli n = 2
sed -n '1,2!p' input-file
!
Średni „wykluczyć ten przedział”. Jak można sobie wyobrazić, można na przykład uzyskać bardziej skomplikowany wynik
sed -n '3,5p;7p'
pokaże linię 3,4,5,7. Większa moc pochodzi z używania wyrażeń regularnych zamiast adresów.
Ograniczeniem jest to, że numery linii muszą być znane z góry.
sed 1,2d
? Prostsze jest zwykle lepsze. Również nic w twoich przykładach nie jest specyficzne dla GNU Sed; wszystkie twoje polecenia używają standardowych funkcji POSIX Sed .
Podczas tail -n +4
gdy plik wyjściowy rozpoczynający się od czwartej linii (wszystkie oprócz pierwszych 3 linii) jest standardowy i przenośny, jego head
odpowiednik ( head -n -3
wszystkie oprócz ostatnich 3 linii) nie jest.
Przenośnie zrobiłbyś:
sed '$d' | sed '$d' | sed '$d'
Lub:
sed -ne :1 -e '1,3{N;b1' -e '}' -e 'P;N;D'
(uwaga, że w niektórych systemach, w których sed
przestrzeń wzorców ma ograniczony rozmiar, nie skaluje się do dużych wartości n
).
Lub:
awk 'NR>3 {print l[NR%3]}; {l[NR%3]=$0}'
Mam nadzieję, że zrozumiałem twoją potrzebę.
Masz kilka sposobów na zrealizowanie swojego żądania:
tail -n$(expr $(cat /etc/passwd|wc -l) - 2) /etc/passwd
Gdzie / etc / passwd to twój plik
Drugie rozwiązanie może być przydatne, jeśli masz duży plik:
my1stline=$(head -n1 /etc/passwd)
my2ndline=$(head -n2 /etc/passwd|grep -v "$my1stline")
cat /etc/passwd |grep -Ev "$my1stline|$my2ndline"
\n
” .. Działa dla wszystkich liczb całkowitych ujemnych innych niż te,-n -0
które w ogóle nic nie zwracają , tak jak-n 0
by to robił (używając: head (GNU coreutils) 7.4) ... Jednak gdy występuje trailing\n
,-n -0
drukuje jak można się spodziewać po-
, tj. drukuje cały plik ... Tak to działa dla wszystkich nie-zerowych wartości ujemnych .. ale-0
nie powiedzie się, gdy nie ma spływu\n