Mam folder zawierający ponad 250 plików o wielkości 2 GB każdy. Muszę wyszukać ciąg / wzorzec w tych plikach i wyświetlić wynik w output
pliku. Wiem, że mogę uruchomić następujące polecenie, ale jest ono zbyt wolne !!
grep mypattern * > output
Chcę to przyspieszyć. Jako programista w Javie wiem, że do przyspieszenia tego procesu można wykorzystać wielowątkowość. Utknąłem, jak zacząć grep
w „trybie wielowątkowym” i zapisać dane wyjściowe w jednym output
pliku.
grep
parallelism
Abhishek
źródło
źródło
Odpowiedzi:
Są na to dwa proste rozwiązania. Zasadniczo za pomocą
xargs
lubparallel
.Podejście xargs:
Można skorzystać
xargs
zfind
co następuje:Gdzie zastąpisz
number_of_processes
maksymalną liczbę procesów, które chcesz uruchomić. Nie gwarantuje to jednak znaczącej wydajności w przypadku ograniczonej wydajności we / wy. W takim przypadku możesz spróbować uruchomić więcej procesów w celu zrekompensowania straconego czasu oczekiwania na operacje we / wy.Ponadto, dzięki włączeniu funkcji find, możesz określić bardziej zaawansowane opcje zamiast tylko wzorów plików, takich jak czas modyfikacji itp.
Jeden z możliwych problemów z tym podejściem, wyjaśniony w komentarzach Stéphane'a, jeśli plików jest niewiele,
xargs
może nie uruchomić dla nich wystarczająco wielu procesów. Jednym z rozwiązań będzie użycie-n
opcjixargs
do określenia, ile argumentów ma pobierać z potoku na raz. Ustawienie-n1
wymusixargs
rozpoczęcie nowego procesu dla każdego pojedynczego pliku. Może to być pożądane zachowanie, jeśli pliki są bardzo duże (jak w przypadku tego pytania) i istnieje stosunkowo niewielka liczba plików. Jeśli jednak same pliki są małe, narzut związany z uruchomieniem nowego procesu może podważyć przewagę równoległości, w którym to przypadku-n
lepsza wartość będzie lepsza. W związku z tym-n
opcja może zostać dokładnie dostosowana do rozmiaru i liczby plików.Podejście równoległe:
Innym sposobem na to jest użycie narzędzia Ole Tange GNU Parallel
parallel
(dostępne tutaj ). Zapewnia to większą kontrolę drobnoziarnistości nad równoległością, a nawet może być rozdzielone na wiele hostów (byłoby to korzystne, jeśli na przykład katalog jest udostępniany). Najprostsza składnia przy użyciu równoległości będzie:find . -type f | parallel -j+1 grep mypattern
gdzie opcja
-j+1
nakazuje równolegle rozpoczęcie jednego procesu przekraczającego liczbę rdzeni na komputerze (może to być pomocne w przypadku ograniczonych zadań we / wy, możesz nawet spróbować zwiększyć liczbę).Równolegle ma również tę zaletę,
xargs
że faktycznie zachowuje porządek wyjścia z każdego procesu i generuje ciągły wynik. Na przykład,xargs
jeśli proces 1 generuje linię powiedzmyp1L1
, proces 2 generuje linięp2L1
, proces 1 generuje inną linięp1L2
, wynikiem będzie:mając na uwadze,
parallel
że wynikiem powinno być:Jest to zwykle bardziej przydatne niż
xargs
wyjście.źródło
-n
w połączeniu z-P
. W przeciwnym raziexargs
może się nie powieść spawnowanie kilku procesów, jeśli jest kilka plików.grep
na plik. Jeśli pliki nie są bardzo duże i jest ich bardzo mało, prawdopodobnie zechcesz to nieco zwiększyć, ponieważ spędzasz czas na uruchamianiu i zatrzymywaniu procesów grep zamiast przeszukiwania plików.Istnieją co najmniej dwa sposoby przyspieszenia grep pod względem procesora:
Jeśli szukasz stałego ciągu zamiast wyrażenia regularnego, określ
-F
flagę;Jeśli twój wzorzec jest tylko ASCII, użyj 8-bitowych ustawień narodowych zamiast UTF-8, np
LC_ALL=C grep ...
.To nie pomoże, jeśli twój dysk twardy jest wąskim gardłem; w takim przypadku prawdopodobnie równoległość też nie pomoże.
źródło
man grep
„Bezpośrednie wywoływanie, ponieważ albo egrep, albo fgrep jest przestarzałe, ale jest zapewnione, aby umożliwić aplikacjom historycznym, które na nich polegają, działać niezmodyfikowane”. Nie jestem pewien, czy to naprawdę ważne, ale jest to to samo, cogrep -F
Jeśli problem nie jest związany z operacjami we / wy, można użyć narzędzia zoptymalizowanego pod kątem przetwarzania wielordzeniowego.
Możesz rzucić okiem na sift ( http://sift-tool.org , wyłączenie odpowiedzialności: Jestem autorem tego narzędzia) lub srebrny wyszukiwarkę ( https://github.com/ggreer/the_silver_searcher ).
srebrny wyszukiwarka ma limit wielkości pliku 2 GB, jeśli używasz wzorca wyrażenia regularnego, a nie wyszukiwania ciągów znaków.
źródło