Usuń linię, jeśli następny wiersz jest taki sam


15

Jakiego polecenia sed / awk mogę użyć? Po prostu sort -uusunie wszystkie wystąpienia

Wejście:

abc
abc
def
abc
abc
def

Oczekiwany wynik:

abc
def
abc
def

Odpowiedzi:


36

Do tego uniqsłuży standardowe polecenie.

uniq your-file

Zauważ, że niektóre uniqimplementacje, takie jak GNU uniq, dadzą ci pierwszą z sekwencji wierszy, które sortują to samo (gdzie strcoll()zwraca 0), w przeciwieństwie do identycznych bajtów po bajcie (gdzie memcmp()lub strcmp()zwraca 0). Aby wymusić porównanie bajt-bajt bez względu na uniqimplementację, możesz wymusić ustawienie regionalne za Cpomocą:

LC_ALL=C uniq your-file

7

Vim potrafi to ładnie osiągnąć:

:g/\v^(.*\n)\1/d

Lub jeśli wolisz używać vima jako narzędzia wiersza poleceń, możesz to zrobić jako

vim file -c "g/\v^(.*\n)\1/d" -c "wq"

W ten sposób nie będziesz musiał walczyć z wychodzącym vimem później;)

Wyjaśnienie:

:g/

Na wszystkich liniach, które pasują do tego wyrażenia regularnego ...

\v^(.*\n)\1

Każda linia, po której następuje sama ...

/d

uruchom polecenie d elete (usuń bieżący wiersz). Należy -c "wq"zapisać zmiany i wyjść.


Zauważ, że przynajmniej w vimie 8.1.2112 nie działa on dla zduplikowanych linii, które są dwiema ostatnimi liniami pliku. Ponadto usuwa tylko jeden duplikat z sekwencji 3 duplikatów linii.
Stéphane Chazelas

1
@ StéphaneChazelas z wyjątkiem tego, że obecnie brakuje specyfikacji pożądanego zachowania w przypadku 3-liniowym - mogłem zobaczyć pożądane zachowanie na dwa sposoby.
D. Ben Knoble,
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.