Zidentyfikuj zduplikowane bloki tekstu w pliku

10

Czy istnieje wygodny sposób na identyfikację zduplikowanych lub prawie zduplikowanych bloków tekstu w pliku?

Chcę tego użyć do identyfikacji duplikacji kodu. Wygląda na to, że istnieją specjalne programy z tą funkcją, ale nie chcę się w to angażować.

Mam nadzieję, że istnieje narzędzie podobne do diff, które może wykonać coś w rodzaju różnicowania „w obrębie pliku”. Jeszcze lepiej byłoby w ramach jednego pliku vimdiff.

Prakseolityczny
źródło
Czego tu vimdiffnie zrobisz?
slm
Ponieważ dotyczy tylko jednego pliku. Nie wiem, jak używać vimdiff na osobnych częściach tego samego pliku.
Praxeolitic
Rozumiem, że tęskniłem za tym, że był to pojedynczy plik.
slm

Odpowiedzi:

13

Jeśli wykonanie porównania linia po linii jest dopuszczalne, następujące informacje powiedzą, które wiersze są duplikowane w pliku texti ile razy każdy z nich się pojawia:

sort text | uniq -c | grep -vE '^\s*1 '

Jako przykład,

$ cat text
alpha
beta
alpha
gamma
alpha
beta
$ sort text | uniq -c | grep -vE '^\s*1 '
      3 alpha
      2 beta

Za pomocą zwykłych narzędzi uniksowych można to rozszerzyć, zakładając, że format testu wejściowego nie jest zbyt skomplikowany, do porównań akapit po akapicie lub zdania po zdaniu.

Znajdowanie powtarzających się akapitów

Załóżmy, że nasz plik textzawiera:

This is a paragraph.

This is another
paragraph

This is
a paragraph.

Last sentence.

Następujące polecenie wskazuje, które akapity pojawiają się więcej niż jeden raz:

$ awk -v RS=""  '{gsub(/\n/," "); print}' text | sort | uniq -c | grep -vE '^\s*1 '
      2 This is a paragraph.

Służy to awkdo dzielenia tekstu na akapity (oznaczone pustymi liniami), konwertuje nowe wiersze na spacje, a następnie przekazuje dane wyjściowe, jeden wiersz na akapit, w celu sortowania i unikania w celu zliczania zduplikowanych akapitów.

Powyższe zostało przetestowane z GNU awk. W przypadku innych awkmetoda definiowania pustych linii jako granic akapitu (zapisu) może się różnić.

John1024
źródło
1
Głosowałbym za wieloma linijkami jednocześnie.
Praxeolitic
1
@Praxeolitic Zaktualizowano dla akapitów.
John1024