Przetwarzanie dużych danych: Usuwanie wierszy w jednym dokumencie tekstowym znalezionym w innym


1

Mam 2 duże pliki tekstowe (~ 500M, ~ 15GB ea), które wyglądają tak:

PlikP.txt:

test@test.com: testtest 
 test@test.com1: testtest1
test@test.com2: testtest2
test@test.com3: testtest3
test@test.com4: testtest4

PlikE.txt

test@test.com:testtest
test@test.com0:testtest0
test@test.com2:testtest2
test@test.com3:testtest3
test@test.com5:testtest5

(Zauważ, jak FileE.txtma linie, które nie są w FileP.txtśrodku. Nie chcę ich uwzględniać. Pogrubione linie to linie, które powinny się w końcu znaleźć output.txt, ponieważ nie są w środku FileE.txt.)

Chcę uruchomić FileE.txtprzed FileP.txti usunąć wszystkie wiersze, które zostały znalezione w FileE.txtod FileP.txti wyjście do nowego pliku.

To powinno wyglądać tak:

Output.txt:

test@test.com1: testtest1
test@test.com4: testtest4

Próbowałem kilku poleceń,

Oto moje polecenie grep:

$ grep -Fvxf FileE.txt FileP.txt > output.txt

Jednak pojawia się ten błąd (oczywiście, ponieważ pliki są zbyt duże):

grep: memory exhausted

Dla zainteresowanych uruchomione $ ulimit -azwroty:

core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
file size               (blocks, -f) unlimited
open files                      (-n) 256
pipe size            (512 bytes, -p) 8
stack size              (kbytes, -s) 2032
cpu time               (seconds, -t) unlimited
max user processes              (-u) 256
virtual memory          (kbytes, -v) unlimited

Więc moje pytanie brzmi: jaki byłby najbardziej wydajny i najłatwiejszy sposób na zakończenie tego procesu?

UWAGA: Pliki nie są sortowane.


Czy pliki są gwarantowane do posortowania? Proszę nie odpowiadać w komentarzach; edytuj swoje pytanie, aby było jaśniejsze i bardziej kompletne.
Scott

1
Posortować pliki, zrobić a diff FileP.txt File.txti zachować tylko wiersze z prefiksem <?
ksenoid

@Scott Done. Jak miałbym zachować linie z prefiksem <? Nigdy nie korzystałem z Diff. Czy tworzy jeden duży folder z <przedrostkiem w wierszach z tą różnicą? Czy to również zachowuje linie, które są dostępne w FileE.txt, które nie istnieją w FileP.txt?
AndrewWilliams,

Inny pomysł? Pobierz je do bazy danych MySQL. Przy tak dużych danych zwykły plik tekstowy nigdy nie jest świetną opcją. Nawet jeśli ta baza danych MySQL jest uważana tylko za ogromną pamięć podręczną. To powiedziawszy, jeśli chcesz pozostać w świecie linii poleceń, odczuwam twój ból.
JakeGould

@JakeGould Myślałem o tym szczerze. Muszę zostać w CL :(
AndrewWilliams, 18'18

Odpowiedzi:


0

Jeśli pliki są posortowane, wykonaj

comm -23 fileP.txt fileE.txt

commporównuje dwa posortowane pliki, szukając wspólnych linii. Na przykład, biorąc pod uwagę ten plik kolorów, których nazwy zaczynają się od spółgłosek:

blue
green
purple
red
white
yellow

i ta lista kolorów, których nazwy kończą się samogłosek:

blue
indigo
orange
purple
white

polecenie comm colors1 colors2tworzy następujące dane wyjściowe:

                blue
green
        indigo
        orange
                purple
red
                white
yellow

gdzie:
pierwsza kolumna zawiera kolory, które zaczynają się i kończą spółgłosek (in colors1ale nie colors2), druga kolumna zawiera kolory, które zaczynają się i kończą samogłoskami (in colors2ale nie colors1), a trzecia kolumna zawiera kolory, które zaczynają się spółgłosek i kończą samogłoskami (zarówno colors1i colors2). comm fileP.txt fileE.txtTworzy pliki (pokazane w pytaniu)

                test@test.com:testtest
        test@test.com0:testtest0
test@test.com1:testtest1
                test@test.com2:testtest2
                test@test.com3:testtest3
test@test.com4:testtest4
        test@test.com5:testtest5

Opcje są trochę nieintuicyjne: -23oznacza pomijanie drugiej i trzeciej kolumny, pokazując tylko pierwszą (linie, które są w pierwszym pliku, ale nie w drugiej). Więc,

$ comm -23 fileP.txt fileE.txt
test@test.com1:testtest1
test@test.com4:testtest4

Pamiętaj, że to nie będzie działać poprawnie, jeśli pliki nie zostaną posortowane. Jeśli pliki nie są sortowane, posortuj je.


0

Aby powiększyć komentarz xenoid , posortuj pliki i wpisz

diff fileP.txt fileE.txt | sed -n 's/^< //p'

Dane wyjściowe diffpokazują wiersze znajdujące się tylko w pierwszym pliku, poprzedzone znakiem , oraz wiersze znajdujące się tylko w drugim pliku, poprzedzone znakiem . W sedzaledwie wybiera linie, które zaczynają się i taśmy ją.

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.