Mám složku, která má 250+ souborů po 2 GB. Potřebuji v těchto souborech vyhledat řetězec/vzor a výsledek vypsat do output
soubor. Vím, že mohu spustit následující příkaz, ale je příliš pomalý!!
grep mypattern * > output
Chci to urychlit. Jako programátor v Javě vím, že multi-threading lze použít pro urychlení procesu. Zasekl jsem se v tom, jak spustit grep
v „multi-threaded mode“ a zapište výstup do jednoho output
soubor.
Přijatá odpověď:
Na to existují dvě snadná řešení. V podstatě pomocí xargs
nebo parallel
.
Přístup xargs:
Můžete použít xargs
pomocí find
takto:
find . -type f -print0 | xargs -0 -P number_of_processes grep mypattern > output
Kde nahradíte number_of_processes
maximálním počtem procesů, které chcete spustit.
Není však zaručeno, že vám to poskytne významný výkon v případě, že je váš výkon omezený I/O. V takovém případě se můžete pokusit spustit více procesů, abyste kompenzovali ztrátu času při čekání na I/O.
Se zahrnutím funkce find můžete také zadat pokročilejší možnosti namísto pouze vzorů souborů, jako je čas úpravy atd…
Jedním z možných problémů s tímto přístupem, jak je vysvětleno v komentářích Stéphana, pokud existuje málo souborů, xargs
nemusí pro ně spustit dostatečně mnoho procesů. Jedním z řešení bude použití -n
možnost pro xargs
k určení, kolik argumentů má převzít z roury najednou. Nastavení -n1
vynutí xargs
pro zahájení nového procesu pro každý jednotlivý soubor. Toto může být žádoucí chování, pokud jsou soubory velmi velké (jako v případě této otázky) a existuje relativně malý počet souborů. Pokud jsou však samotné soubory malé, může režie spuštění nového procesu podkopat výhodu paralelismu, v takovém případě větší -n
hodnota bude lepší. Tedy -n
možnost může být doladěna podle velikosti a počtu souborů.
Paralelní přístup:
Dalším způsobem, jak to udělat, je použít nástroj Ole Tange GNU Parallel parallel
, (k dispozici zde). To nabízí lepší kontrolu nad paralelismem a může být dokonce distribuováno na více hostitelů (to by bylo výhodné, pokud je například sdílen váš adresář).
Nejjednodušší syntaxe využívající paralelu bude:
find . -type f | parallel -j+1 grep mypattern
kde je volba -j+1
instruuje paralelně ke spuštění jednoho procesu, který překračuje počet jader na vašem počítači (To může být užitečné u úloh s omezeným I/O, můžete dokonce zkusit zvýšit počet).
Parallel má také výhodu oproti xargs
skutečné zachování pořadí výstupu z každého procesu a generování souvislého výstupu. Například pomocí xargs
, pokud proces 1 generuje řádek, řekněme p1L1
, proces 2 vygeneruje řádek p2L1
, proces 1 vygeneruje další řádek p1L2
, výstup bude:
p1L1
p2L1
p1L2
zatímco s parallel
výstup by měl být:
p1L1
p1L2
p2L1
To je obvykle užitečnější než xargs
výstup.