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.