Różnicowanie dwóch dużych plików tekstowych

32

Mam dwa duże pliki (po 6 GB). Są nieposortowane, z \nseparatorami linii ( ). Jak mogę je odróżnić? Powinno to zająć mniej niż 24 godziny.

jonasl
źródło

Odpowiedzi:

45

Najbardziej oczywistą odpowiedzią jest użycie polecenia diff i prawdopodobnie dobrym pomysłem jest dodanie do niego parametru --speed-large-files.

diff --speed-large-files a.file b.file

Wspominasz o nieposortowanych plikach, więc może najpierw musisz je posortować

sort a.file > a.file.sorted
sort b.file > b.file.sorted
diff --speed-large-files a.file.sorted b.file.sorted

możesz zapisać tworzenie dodatkowego pliku wyjściowego, przesyłając dane wyjściowe 2. sortowania bezpośrednio do pliku różnicowego

sort a.file > a.file.sorted
sort b.file | diff --speed-large-files a.file.sorted -

Oczywiście będą działać najlepiej w systemie z dużą ilością dostępnej pamięci i prawdopodobnie będziesz potrzebować dużo wolnego miejsca na dysku.

Z twojego pytania nie było jasne, czy próbowałeś ich już wcześniej. Jeśli tak, to warto wiedzieć, co poszło nie tak (zajęło to zbyt wiele czasu itp.). Zawsze odkryłem, że polecenia sortowania i porównywania zapasów zwykle wykonują co najmniej tak samo, jak polecenia niestandardowe, chyba że istnieją pewne bardzo specyficzne dla domeny właściwości plików, które pozwalają robić różne rzeczy.

Richm
źródło
2
+1. Możesz pominąć wszystkie pliki tymczasowe o nazwanych potokach. Użyj, mkfifoaby utworzyć [ab].file.sortedprzed użyciem ich jako danych wyjściowych sort. Umieść oba sorts &w tle i użyj obu potoków jako nazw plików dla diff.
krissi
15
@krissi Możesz również osiągnąć ten sam efekt, używając następującej składni:diff <(command 1) <(command 2)
Michael Mrozek
Dzięki działało. Potrzebowałem kilku GB pamięci, ale naprawiłem to
sekundowe
7
Jeśli ktoś taki jak ja zastanawia się, dlaczego <(cmd1) <(cmd2)działa składnia (ponieważ brzmi to jak dwukierunkowe przekierowanie standardowego wejścia!), Spróbuj echo hello <(cmd1) <(cmd2). Zobaczysz coś, hello /dev/fd/63 /dev/fd/62co nagle wyjaśnia;)
Alex
3
Z mojego doświadczenia --speed-large-fileswynika , że ta opcja nie pomaga, jeśli nie masz wystarczającej ilości pamięci RAM. Ponadto wstępne sortowanie nie jest pomocne, jeśli masz wielowierszową strukturę rekordów, którą chcesz zachować. Opcje, o których mowa powyżej (przez @unhammer) są interesujące, ale wyjście z rdiffi bsdiffjest raczej binarny. Instalacja bdiffz Heirloom Toolbox wygląda jak zadanie dostrajania (wymaga devtools Heirloom, wymarłych plików nagłówkowych,…). Czy to naprawdę warte wysiłku? Czy są inne alternatywy?
Christian Pietsch
5

Sortowanie danych wejściowych i informowanie diffprogramu, że dane wejściowe są sortowane, zapewni ogromne przyspieszenie. Nie znam żadnej diffz taką opcją, ale commzakłada posortowane dane wejściowe i będzie znacznie szybsze, jeśli wystarczy dla twoich celów.

Karl
źródło
commdziałał świetnie do tego, nigdy wcześniej o nim nie słyszałem, ale najwyraźniej jest w coreutils.
theferrit32