J'ai un dossier contenant plus de 250 fichiers de 2 Go chacun. Je dois rechercher une chaîne/un modèle dans ces fichiers et afficher le résultat dans une output
dossier. Je sais que je peux exécuter la commande suivante, mais c'est trop lent !!
grep mypattern * > output
Je veux l'accélérer. En tant que programmeur en Java, je sais que le multi-threading peut être utilisé pour accélérer le processus. Je ne sais pas comment démarrer grep
en "mode multi-thread" et écrivez la sortie dans une seule output
fichier.
Réponse acceptée :
Il existe deux solutions simples pour cela. Fondamentalement, en utilisant xargs
ou parallel
.
Approche xargs :
Vous pouvez utiliser xargs
avec find
comme suit :
find . -type f -print0 | xargs -0 -P number_of_processes grep mypattern > output
Où vous remplacerez number_of_processes
par le nombre maximum de processus que vous souhaitez lancer.
Cependant, cela ne garantit pas une performance significative si vos performances sont limitées en E/S. Dans ce cas, vous pouvez essayer de démarrer plus de processus pour compenser le temps perdu à attendre les E/S.
De plus, avec l'inclusion de find, vous pouvez spécifier des options plus avancées au lieu de simplement des modèles de fichiers, comme l'heure de modification, etc…
Un problème possible avec cette approche comme expliqué par les commentaires de Stéphane, s'il y a peu de fichiers, xargs
peut ne pas démarrer suffisamment de processus pour eux. Une solution sera d'utiliser le -n
option pour xargs
pour spécifier combien d'arguments doit-il prendre du tube à la fois. Réglage -n1
forcera xargs
pour démarrer un nouveau processus pour chaque fichier. Cela peut être un comportement souhaité si les fichiers sont très volumineux (comme dans le cas de cette question) et qu'il y a un nombre relativement petit de fichiers. Cependant, si les fichiers eux-mêmes sont petits, la surcharge de démarrage d'un nouveau processus peut miner l'avantage du parallélisme, auquel cas un plus grand -n
la valeur sera meilleure. Ainsi, le -n
l'option peut être affinée en fonction de la taille et du nombre de fichiers.
Approche parallèle :
Une autre façon de le faire est d'utiliser l'outil Ole Tange GNU Parallel parallel
, (disponible ici). Cela offre un contrôle plus précis du parallélisme et peut même être distribué sur plusieurs hôtes (ce serait avantageux si votre répertoire est partagé par exemple).
La syntaxe la plus simple utilisant le parallèle sera :
find . -type f | parallel -j+1 grep mypattern
où l'option -j+1
ordonne en parallèle de démarrer un processus dépassant le nombre de cœurs sur votre machine (cela peut être utile pour les tâches limitées en E/S, vous pouvez même essayer d'augmenter le nombre).
Parallel a également l'avantage sur xargs
de conserver réellement l'ordre de la sortie de chaque processus et de générer une sortie contiguë. Par exemple, avec xargs
, si le processus 1 génère une ligne, dites p1L1
, le processus 2 génère une ligne p2L1
, le processus 1 génère une autre ligne p1L2
, le résultat sera :
p1L1
p2L1
p1L2
alors qu'avec parallel
la sortie devrait être :
p1L1
p1L2
p2L1
Ceci est généralement plus utile que xargs
sortie.