Usuń ostatnią linię z pliku


44

Używam sed do szybkiego usuwania linii o określonej pozycji jako

sed '1d'
sed '5d'

Ale co, jeśli chcę usunąć ostatni wiersz pliku i nie znam liczby wierszy (wiem, że mogę to zrobić za pomocą wckilku innych sztuczek).

Obecnie za pomocą obejścia tego problemu headi w tailpołączeniu z nim wc. Jakieś szybkie zwroty tutaj?


Który OS? Niektóre smaki mają ciekawe opcje headi tail...
Nils,

@Nils Jestem na 'Red Hat Enterprise Linux Server wersja 5.5 (Tikanga)'. Czy możesz wskazać opcje headi tailznasz różne smaki?
Mt

Zrobiłem. Patrz poniżej.
Nils,

Odpowiedzi:


87

w sed $jest ostatnim wierszem, więc aby usunąć ostatni wiersz:

sed '$d' <file>

12
Służy sed -i '$d' <file>do edycji pliku na miejscu.
WanderingMind

1
Co by było, gdyby usunąć ostatnie n wierszy, gdzie n jest dowolną liczbą całkowitą?
Joshua Salazar

31

$ za ostatnią linię:

sed '$d' file

9
pokonać cię o 30 sekund: P
h3rrmiller

1
Niestety, trzeba usunąć bardziej skomplikowane techniki, powiedzmy, ostatnie dwa wiersze.
dubiousjim

Co masz na myśli? sed '$d' file; sed '$d' file
Rob

3
@Rob: sed '$d' filetak naprawdę nie modyfikuje pliku; po prostu drukuje zawartość pliku, minus ostatni wiersz. Tak więc sed '$d' file; sed '$d' filewydrukuje zawartość pliku dwukrotnie , za każdym razem minus ostatni wiersz. Odpowiednik usuwania ostatnich dwóch linii sed '$d' fileto sed '$d' file | sed '$d'.
ruakh

2
Tak, to nieeleganckie, ale oczywiście działa. Zrobiłbym to za jednym razem sed -n '1{h;n;}; $q; x; p;'. Nadąsałem się, że nie możemy tego zrobić sed '$-1,$d'.
dubiousjim

14

cat file.txt | head -n -1 > new_file.txt

Uważaj, wydaje się, że w zależności od ostatniego wiersza file.txt(jeśli kończy się na EOF, \na następnie EOF), liczba wierszy new_file.txtmoże być taka sama (jak file.txt) po tym poleceniu (dzieje się tak, gdy nie ma \n) - w każdym razie, zawartość ostatniego wiersza zostanie usunięta.

Pamiętaj też, że musisz użyć drugiego (pośredniego) pliku. Jeśli przechwycisz i przekierujesz do tego samego pliku, usuniesz go.


6
Tam, gdzie to działa, może być również po prostu head -n -1 file.txt > new_file.txt. Należy jednak pamiętać, że ujemne liczenie head -njest dostępne tylko dla niektórych implementacji head. Na przykład nie działa dla FreeBSD ani dla wersji BusyBox head.
dubiousjim

1
@dubiousjim: Uzgodniony, head -n -1 file.txt > new_file.txtjest lepszy. Działa to w ten sam sposób w odniesieniu do moich dwóch komentarzy (ta sama liczba wierszy i usuwanie w tym samym pliku). Co do argumentu negatywnego, takie różnice występują od czasu do czasu między Unixami i często są frustrujące, ponieważ oczekujesz, że będzie to w całości to samo polecenie (i dlaczego nie miałbyś - tej samej nazwy i celu!) - w każdym razie dobre punkt. (Używam Debiana.)
Emanuel Berg,

5

head --lines=-1. Najpierw natknąłem się na tę możliwość na stronie podręcznika użytkownika na temat systemu SLES11SP2 (coreutils-8.12-6.23.1)

taili headsą częścią coreutils-rpm (przynajmniej dla systemów opartych na rpm).

Zgodnie z dziennikiem zmian coreutils ta składnia jest obsługiwana od wersji coreutils 5.0.1

Złe wieści: Według strony podręcznika RH5 ta opcja nie jest opisana

Dobra wiadomość: działa z RH5 (więc w twoim przypadku: działa - przynajmniej z bieżącą wersją RH5).

rpm -q coreutils pokazuje mi (na CentOS 5.8): coreutils-5.97-34.el5_8.1

Nie jestem pewien, czy RH5.5. ma już wersję coreutils, która ją obsługuje. Ale 5.5 i tak ma EoLed.


+1. działa idealnie na RH5.5. Dzięki.
mtk

0

Linux

$ jest ostatnim wierszem, d do usunięcia:

sed '$d' ~/path/to/your/file/name

System operacyjny Mac

Odpowiednik sed--i

sed -i '' -e '$ d' ~/path/to/your/file/name
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.