Robię to jednak algorytmicznie, nie wydaje się to być najbardziej wydajnym podejściem (O (n log n) * avg_line_len gdzie n jest liczbą linii). Pracuję na plikach o wielkości kilku gigabajtów, więc kluczową kwestią jest wydajność. Zastanawiam się, czy istnieje narzędzie, które wykonuje tylko zliczanie w jednym przebiegu przy użyciu drzewa prefiksów (w moim przypadku ciągi często mają wspólne prefiksy) lub podobne, które powinny załatwić sprawę w O (n) * avg_line_len. Czy ktoś zna takie narzędzie wiersza polecenia?
Droggl
21
Dodatkowym krokiem jest przekazanie danych wyjściowych do końcowego polecenia „sort -n”. To posortuje wyniki według najczęściej występujących linii.
samoz
79
Jeśli chcesz wydrukować tylko zduplikowane linie, użyj „uniq -d”
DmitrySandalov
6
Jeśli chcesz ponownie posortować wynik, możesz użyć sortponownie w następujący sposób:sort <file> | uniq -c | sort -n
Abhishek Kashyap
413
Spowoduje to wydrukowanie tylko zduplikowanych linii z podaniem:
Dobra uwaga z opcją --repeated lub -d. O wiele bardziej dokładne niż używanie „| grep 2” lub podobnego!
Lauri
Jak zmodyfikować to polecenie, aby pobrać wszystkie wiersze, których liczba powtórzeń przekracza 100?
Black_Rider
@Black_Rider Dodanie | sort -nlub | sort -nrdo potoku posortuje dane wyjściowe według liczby powtórzeń (odpowiednio rosnąco lub malejąco). Nie o to pytasz, ale pomyślałem, że to może pomóc.
Andrea
1
@Black_Rider awk wydaje się być w stanie wykonać wszelkiego rodzaju obliczenia: w twoim przypadku możesz to zrobić| awk '$1>100'
awk '{dups[$1]++} END{for (num in dups) {print num,dups[num]}}' data
W awk 'dups[$1]++'poleceniu zmienna $1przechowuje całą zawartość kolumny 1, a nawiasy kwadratowe mają dostęp do tablicy. Tak więc, dla każdej pierwszej kolumny linii w datapliku, węzeł nazwanej tablicy dupsjest zwiększany.
Na koniec zapętlamy dupstablicę numjako zmienną i najpierw wypisujemy zapisane liczby, a następnie ich liczbę zduplikowanych wartości dups[num].
Zauważ, że twój plik wejściowy ma spacje na końcu niektórych linii, jeśli je wyczyścisz, możesz użyć $0zamiast $1polecenia in powyżej :)
Czy to nie jest przesada, biorąc pod uwagę, że mamy uniq?
Nathan Fellman,
9
sort | uniqa rozwiązanie awk ma całkiem inną kompromis między wydajnością i zasobami: jeśli pliki są duże, a liczba różnych linii jest niewielka, rozwiązanie awk jest znacznie wydajniejsze. Jest liniowy pod względem liczby linii, a wykorzystanie miejsca jest liniowe pod względem liczby różnych linii. OTOH, rozwiązanie awk musi zachować wszystkie różne linie w pamięci, podczas gdy sortowanie (GNU) może uciekać się do plików tymczasowych.
Lars Noschinski
14
W systemie Windows za pomocą „Windows PowerShell” użyłem polecenia wymienionego poniżej, aby to osiągnąć
Zasadniczo: przekonwertuj wszystkie znaki spacji na podziały wierszy, a następnie posortuj przetłumaczone dane wyjściowe i podaj je do uniq i policz duplikaty linii.
Odpowiedzi:
Zakładając, że w jednym wierszu jest jedna liczba:
Możesz użyć bardziej szczegółowej
--count
flagi również w wersji GNU, np. W systemie Linux:źródło
sort
ponownie w następujący sposób:sort <file> | uniq -c | sort -n
Spowoduje to wydrukowanie tylko zduplikowanych linii z podaniem:
lub, z długimi opcjami GNU (w systemie Linux):
na BSD i OSX musisz użyć grep, aby odfiltrować unikalne linie:
W podanym przykładzie wynik byłby następujący:
Jeśli chcesz wydrukować liczby dla wszystkich linii, w tym tych, które pojawiają się tylko raz:
lub, z długimi opcjami GNU (w systemie Linux):
Dla danych wejściowych dane wyjściowe to:
Aby posortować dane wyjściowe z najczęstszymi wierszami na górze, możesz wykonać następujące czynności (aby uzyskać wszystkie wyniki):
lub, aby uzyskać tylko zduplikowane linie, najczęściej:
w OSX i BSD wersja ostateczna staje się:
źródło
| sort -n
lub| sort -nr
do potoku posortuje dane wyjściowe według liczby powtórzeń (odpowiednio rosnąco lub malejąco). Nie o to pytasz, ale pomyślałem, że to może pomóc.| awk '$1>100'
sort FILE | uniq -c | grep -v '^ *1 '
Aby znaleźć i policzyć zduplikowane linie w wielu plikach, możesz wypróbować następujące polecenie:
lub:
źródło
Przez awk:
W
awk 'dups[$1]++'
poleceniu zmienna$1
przechowuje całą zawartość kolumny 1, a nawiasy kwadratowe mają dostęp do tablicy. Tak więc, dla każdej pierwszej kolumny linii wdata
pliku, węzeł nazwanej tablicydups
jest zwiększany.Na koniec zapętlamy
dups
tablicęnum
jako zmienną i najpierw wypisujemy zapisane liczby, a następnie ich liczbę zduplikowanych wartościdups[num]
.Zauważ, że twój plik wejściowy ma spacje na końcu niektórych linii, jeśli je wyczyścisz, możesz użyć
$0
zamiast$1
polecenia in powyżej :)źródło
uniq
?sort | uniq
a rozwiązanie awk ma całkiem inną kompromis między wydajnością i zasobami: jeśli pliki są duże, a liczba różnych linii jest niewielka, rozwiązanie awk jest znacznie wydajniejsze. Jest liniowy pod względem liczby linii, a wykorzystanie miejsca jest liniowe pod względem liczby różnych linii. OTOH, rozwiązanie awk musi zachować wszystkie różne linie w pamięci, podczas gdy sortowanie (GNU) może uciekać się do plików tymczasowych.W systemie Windows za pomocą „Windows PowerShell” użyłem polecenia wymienionego poniżej, aby to osiągnąć
Możemy również użyć polecenia cmdlet where-object do filtrowania wyniku
źródło
Zakładając, że masz dostęp do standardowej powłoki Unix i / lub środowiska cygwin:
Zasadniczo: przekonwertuj wszystkie znaki spacji na podziały wierszy, a następnie posortuj przetłumaczone dane wyjściowe i podaj je do uniq i policz duplikaty linii.
źródło