Mam duży plik zawierający jeden ciąg w każdej linii. Chciałbym móc szybko ustalić, czy ciąg znajduje się w pliku. Najlepiej byłoby to zrobić przy użyciu algorytmu typu binarnego.
Niektórzy Googling ujawnili look
polecenie z -b
flagą, która obiecuje zlokalizować i wyprowadzić wszystkie ciągi zaczynające się od danego prefiksu za pomocą algorytmu wyszukiwania binarnego. Niestety, wydaje się, że nie działa poprawnie i zwraca wyniki null dla ciągów, które, jak wiem, znajdują się w pliku (są one poprawnie zwracane przez równoważne grep
wyszukiwanie).
Czy ktoś wie o innym narzędziu lub strategii skutecznego wyszukiwania tego pliku?
look
polecenie działało poprawnie, ponieważ wygląd wydaje się ignorować ustawienia regionalne i po prostu używa C jak sortowania na stałe, otworzyłem również błąd z powodu tego mylącego zachowania: bugzilla.kernel.org/show_bug.cgi?id=198011look -b
nie udało mi się z błędemFile too large
. Myślę, że stara się wczytać całą rzecz do pamięci.Odpowiedzi:
Istnieje zasadnicza różnica między
grep
ilook
:O ile wyraźnie nie zaznaczono inaczej,
grep
znajdzie wzory nawet gdzieś w linii. Dlalook
stanów strony:Nie używam
look
zbyt często, ale zadziałało dobrze na trywialnym przykładzie, który właśnie wypróbowałem.źródło
egrep "^TEST" sortedlist.txt | wc -l
, otrzymam 41 289 wyników. Jednak równoważnelook
polecenialook -b TEST sortedlist.txt | wc -l
dają tylko wyniki z 1995 roku. Prawie zastanawiam się, czy jest jakiś błądlook
.look
używa innych ustawień sortowania niż program użyty do sortowania pliku.Może trochę spóźniona odpowiedź:
Sgrep ci pomoże.
Sgrep (sorted grep) przeszukuje posortowane pliki wejściowe w poszukiwaniu linii pasujących do klucza wyszukiwania i wyświetla pasujące linie. Podczas wyszukiwania dużych plików sgrep jest znacznie szybszy niż tradycyjny uniksowy grep, ale ze znacznymi ograniczeniami.
Możesz pobrać źródło tutaj: https://sourceforge.net/projects/sgrep/?source=typ_redirect
oraz dokumenty tutaj: http://sgrep.sourceforge.net/
Inny sposób:
Nie wiem, jak duży jest plik. Może powinieneś spróbować równolegle:
/programming/9066609/fastest-possible-grep
Zawsze robię grep z plikami o rozmiarze> 100 GB, działa dobrze.
źródło
sudo apt-get install sgrep
aby uzyskać sgrep, sgrep w repozytoriach buntu nie jest tak naprawdę sgrep, nie jestem pewien, czy to to samo.Możesz haszować plik na części, a następnie grepować tylko żądany element:
wtedy odnośnik wyglądałby następująco:
To robi dwie rzeczy:
źródło
sgrep może dla ciebie działać:
Strona projektu http://sgrep.sourceforge.net/ mówi:
Myślę jednak, że w przypadku wstawiania nie ma lepszego rozwiązania niż użycie bazy danych: /programming/10658380/shell-one-liner-to-add-a-line-to-a-sorted-file/ 33859372 # 33859372
źródło
sgrep
repozytoriach Ubuntu znajduje się tak naprawdę sgrep , który jest zaprojektowany do „przeszukiwania pliku w poszukiwaniu wzorca strukturalnego” i nie ma nic wspólnego z wyszukiwaniem binarnym.Jeśli chcesz to naprawdę szybko (O (1) szybko), możesz zbudować zestaw skrótów, aby sprawdzić. Nie mogłem znaleźć implementacji, która pozwoliłaby mi przechowywać wcześniej zbudowany zestaw skrótów w pliku i sondować go bez konieczności odczytywania całego pliku do pamięci, więc utworzyłem własny .
Zbuduj zestaw skrótów (
-b
/--build
):Sprawdź zestaw skrótów (
-p
/--probe
):… Lub z ciągiem znaków do wyszukiwania na standardowym wejściu:
Możesz wyciszyć wyjście za
--probe
pomocą opcji-q
/--quiet
, jeśli interesuje Cię tylko status wyjścia:Aby uzyskać więcej opcji, zobacz opis użytkowania dostępny za pośrednictwem
-h
/--help
opcji lub w dołączonymREADME
pliku.źródło