Usuń zduplikowane linie bez sortowania [duplicate]

to pytanie ma już odpowiedzi tutaj : Jak usunąć zduplikowane linie w pliku bez sortowania go w Uniksie? (9 odpowiedzi) Zamknięty 2 lata temu .

Mam skrypt narzędzia w Pythonie:

#!/usr/bin/env python
import sys
unique_lines = []
duplicate_lines = []
for line in sys.stdin:
  if line in unique_lines:
    duplicate_lines.append(line)
  else:
    unique_lines.append(line)
    sys.stdout.write(line)
# optionally do something with duplicate_lines

Ta prosta funkcjonalność (uniq bez konieczności sortowania, stabilna kolejność) musi być dostępna jako proste narzędzie uniksowe, prawda? Może kombinacja filtrów w rurze?

Powód pytania: potrzeba tej funkcjonalności w systemie, na którym nie mogę wykonać Pythona z dowolnego miejsca.

Author: Matthias Braun, 2012-07-17

8 answers

The Unix Bash Scripting blog sugeruje:

awk '!x[$0]++'

To polecenie mówi awk, które linie wydrukować. Zmienna $0 przechowuje całą zawartość linii, a nawiasy kwadratowe mają dostęp do tablicy. Tak więc dla każdej linii pliku węzeł tablicy x jest zwiększany, a linia drukowana, jeśli zawartość tego węzła nie była (!) wcześniej ustawiona.

 293
Author: Michael Hoffman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-19 16:06:28

[9]] późna odpowiedź - właśnie natknąłem się na duplikat tego-ale może warto dodać...

Zasada odpowiedzi @1_cr może być napisana bardziej zwięźle, używając cat -n zamiast awk do dodania liczb w wierszu:

cat -n file_name | sort -uk2 | sort -n | cut -f2-
  • użyj cat -n, aby poprzedzać numery linii
  • Użyj sort -u Usuń zduplikowane dane (-k2 mówi 'zacznij od pola 2 dla klucza sortowania')
  • użyj sort -n do sortowania według liczby
  • użyj cut, aby usunąć numerację linii (-f2- mówi 'wybierz pole 2 till end")
 71
Author: Digital Trauma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-29 17:12:45

Aby usunąć duplikat z 2 Plików:

awk '!a[$0]++' file1.csv file2.csv
 8
Author: AzizSM,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-22 03:32:34

Rozwiązanie Michaela Hoffmana powyżej jest krótkie i słodkie. W przypadku większych plików podejście Schwartziana polegające na dodaniu pola indeksu za pomocą awk, po którym następuje wiele rund sortowania i uniq wymaga mniej pamięci. Poniższy fragment działa w bash

awk '{print(NR"\t"$0)}' file_name | sort -t$'\t' -k2,2 | uniq --skip-fields 1 | sort -k1,1 -t$'\t' | cut -f2 -d$'\t'
 5
Author: iruvar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-23 16:43:38

Teraz możesz sprawdzić to małe narzędzie napisane w Rust: uq .

Wykonuje filtrowanie unikalności bez konieczności najpierw sortowania danych wejściowych, dlatego może być stosowany na ciągłym strumieniu.

 4
Author: Shou Ya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-30 08:45:33

Thanks 1_cr! Potrzebowałem "uniq-u" (Usuń duplikaty całkowicie) zamiast uniq (zostaw 1 kopię duplikatów). Rozwiązania awk i Perla nie można tak naprawdę zmodyfikować, aby to zrobić, twoje mogą! Mogłem też potrzebować niższego zużycia pamięci, ponieważ będę uniq ' ING jak 100,000,000 linii 8-). Na wypadek, gdyby ktoś jeszcze tego potrzebował, po prostu wstawiam "- u"w części uniq komendy:

awk '{print(NR"\t"$0)}' file_name | sort -t$'\t' -k2,2 | uniq -u --skip-fields 1 | sort -k1,1 -t$'\t' | cut -f2 -d$'\t'
 2
Author: hwertz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-23 18:26:14

Chciałem tylko usunąć wszystkie duplikaty w następujących wierszach, nie wszędzie w pliku. Więc użyłem:

awk '{
  if ($0 != PREVLINE) print $0;
  PREVLINE=$0;
}'
 -1
Author: speedolli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-05 10:50:59

Polecenie uniq działa w aliasie parzystym http://man7.org/linux/man-pages/man1/uniq.1.html

 -1
Author: Master James,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-06 11:03:21