J'ai un dossier qui a plus de 250 fichiers de 2 Go chacun. Je dois rechercher une chaîne / un motif dans ces fichiers et afficher le résultat dans un output
fichier. Je sais que je peux exécuter la commande suivante, mais elle est trop lente !!
grep mypattern * > output
Je veux accélérer les choses. En tant que programmeur en Java, je sais que le multi-threading peut être utilisé pour accélérer le processus. Je suis coincé sur la façon de démarrer grep
en "mode multi-thread" et d'écrire la sortie dans un seul output
fichier.
grep
parallelism
Abhishek
la source
la source
Réponses:
Il existe deux solutions faciles pour cela. Fondamentalement, en utilisant
xargs
ouparallel
.Approche de xargs:
Vous pouvez utiliser
xargs
avecfind
comme suit:Où vous allez remplacer
number_of_processes
par le nombre maximal de processus que vous souhaitez lancer. Toutefois, cela ne garantit pas une performance significative au cas où vos performances seraient limitées en entrées / sorties. Dans ce cas, vous pouvez essayer de démarrer plusieurs processus pour compenser le temps perdu à attendre des E / S.En outre, avec l’inclusion de find, vous pouvez spécifier des options plus avancées au lieu de simplement des modèles de fichiers, tels que la date de modification, etc.
Un problème possible avec cette approche, comme l'expliquent les commentaires de Stéphane,
xargs
peut ne pas démarrer suffisamment de processus s'il y a peu de fichiers . Une solution consiste à utiliser l'-n
option pourxargs
spécifier le nombre d'arguments à prendre à la fois dans le canal. Le réglage-n1
obligeraxargs
à démarrer un nouveau processus pour chaque fichier. Ce comportement peut être souhaité si les fichiers sont très volumineux (comme dans le cas de cette question) et si le nombre de fichiers est relativement petit. Toutefois, si les fichiers eux-mêmes sont petits, les frais généraux liés au démarrage d’un nouveau processus risquent de compromettre l’avantage du parallélisme, auquel cas une-n
valeur plus grande sera meilleure. Ainsi, l'-n
option peut être ajusté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 meilleur contrôle du parallélisme et peut même être réparti sur plusieurs hôtes (serait avantageux si votre répertoire est partagé, par exemple). La syntaxe la plus simple utilisant parallèle sera:find . -type f | parallel -j+1 grep mypattern
lorsque l'option
-j+1
indique en parallèle de démarrer un processus au-delà du nombre de cœurs sur votre machine (cela peut être utile pour les tâches limitées d'E / S, vous pouvez même essayer d'augmenter le nombre).Parallèle a également l'avantage
xargs
de conserver réellement l'ordre de la sortie de chaque processus et de générer une sortie contiguë. Par exemple, avecxargs
, si le processus 1 génère une lignep1L1
, le processus 2 génère une lignep2L1
, le processus 1 génère une autre lignep1L2
, le résultat sera:alors qu'avec
parallel
la sortie devrait être:Ceci est généralement plus utile que la
xargs
sortie.la source
-n
en combinaison avec-P
. Sinon, il estxargs
possible que plusieurs processus ne soient pas générés s'il y a deux fichiers.grep
par fichier. À moins que les fichiers ne soient très volumineux et qu’ils soient très peu nombreux, vous voudrez probablement l’augmenter un peu car vous passerez votre temps à démarrer et à arrêter des processus grep au lieu de chercher dans des fichiers.Il y a au moins deux façons d'accélérer le traitement de grep par le processeur:
Si vous recherchez une chaîne fixe plutôt qu'une expression régulière, spécifiez l'
-F
indicateur.Si votre modèle est uniquement ASCII, utilisez une locale 8 bits au lieu de UTF-8, par exemple
LC_ALL=C grep ...
.Cela n’aidera pas si votre disque dur est le goulot d’étranglement; dans ce cas, la parallélisation ne vous aidera probablement pas non plus.
la source
man grep
"L'invocation directe comme étant egrep ou fgrep est obsolète, mais est fournie pour permettre aux applications historiques qui en dépendent de s'exécuter sans modification". Je ne suis pas sûr que cela compte vraiment, mais c'est la même chose quegrep -F
Si le problème n'est pas lié aux E / S, vous pouvez utiliser un outil optimisé pour le traitement multicœur.
Vous voudrez peut-être jeter un oeil à tamiser ( http://sift-tool.org , disclaimer: je suis l'auteur de cet outil) ou le chercheur d'argent ( https://github.com/ggreer/the_silver_searcher ).
Silver Searcher a une limite de taille de fichier de 2 Go si vous utilisez un motif regex et non une recherche par chaîne.
la source