Bash
Parallèle
Recherche…
Introduction
Les travaux dans GNU Linux peuvent être parallélisés en utilisant GNU Parallel. Un travail peut être une commande unique ou un petit script à exécuter pour chacune des lignes de l'entrée. L'entrée type est une liste de fichiers, une liste d'hôtes, une liste d'utilisateurs, une liste d'URL ou une liste de tables. Un travail peut également être une commande qui lit à partir d'un tube.
Syntaxe
- parallel [options] [commande [arguments]] <list_of_arguments>
Paramètres
Option | La description |
---|---|
-jn | Exécutez n jobs en parallèle |
-k | Garder le même ordre |
-X | Plusieurs arguments avec remplacement du contexte |
--colsep regexp | Fractionner l'entrée sur regexp pour les remplacements de position |
{} {.} {/} {/.} {#} | Cordes de remplacement |
{3} {3.} {3/} {3/.} | Chaînes de remplacement positionnelles |
-S sshlogin | Example: [email protected] |
--trc {}.bar | Abréviation de --transfer --return {} .bar --cleanup |
--onall | Exécuter la commande donnée avec un argument sur tous les sshlogins |
--nonall | Exécuter la commande donnée sans arguments sur tous les sshlogins |
--pipe | Split stdin (entrée standard) à plusieurs tâches. |
--recend str | Séparateur de fin d'enregistrement pour --pipe. |
--recstart str | Séparateur de début d'enregistrement pour --pipe. |
Paralléliser les tâches répétitives sur la liste des fichiers
De nombreuses tâches répétitives peuvent être effectuées plus efficacement si vous utilisez davantage de ressources de votre ordinateur (c.-à-d. Les processeurs et la RAM). Vous trouverez ci-dessous un exemple d'exécution de plusieurs tâches en parallèle.
Supposons que vous ayez une < list of files >
, disons la sortie de ls
. De plus, laissez ces fichiers bz2 compressés et réglez-les dans l'ordre suivant.
- Décompressez les fichiers bz2 en utilisant
bzcat
pour stdout - Lignes Grep (par exemple, filtre) avec des mots-clés spécifiques utilisant
grep <some key word>
- Pipe la sortie à concaténer en un seul fichier gzippé en utilisant
gzip
Exécuter ceci en utilisant une boucle while peut ressembler à ceci
filenames="file_list.txt"
while read -r line
do
name="$line"
## grab lines with puppies in them
bzcat $line | grep puppies | gzip >> output.gz
done < "$filenames"
En utilisant GNU Parallel, nous pouvons exécuter 3 travaux parallèles en même temps en faisant simplement
parallel -j 3 "bzcat {} | grep puppies" ::: $( cat filelist.txt ) | gzip > output.gz
Cette commande est simple, concise et plus efficace lorsque le nombre de fichiers et la taille du fichier sont importants. Les jobs sont initiés en parallel
, l'option -j 3
lance 3 jobs parallèles et l'entrée dans les jobs parallèles est effectuée par :::
. La sortie est finalement acheminée vers gzip > output.gz
Paralléliser STDIN
Maintenant, imaginons que nous avons un fichier volumineux (par exemple 30 Go) qui doit être converti ligne par ligne. Disons que nous avons un script, convert.sh
, qui fait cela <task>
. Nous pouvons canaliser le contenu de ce fichier en stdin pour que parallel soit utilisé et avec des morceaux tels que
<stdin> | parallel --pipe --block <block size> -k <task> > output.txt
où <stdin>
peut provenir de quelque chose comme cat <file>
.
Comme exemple reproductible, notre tâche sera nl -n rz
. Prenez n'importe quel fichier, le mien sera data.bz2
et passez-le à <stdin>
bzcat data.bz2 | nl | parallel --pipe --block 10M -k nl -n rz | gzip > ouptput.gz
L'exemple ci-dessus prend <stdin>
partir de bzcat data.bz2 | nl
, où output.gz
nl
juste comme preuve de concept que la sortie finale output.gz
sera enregistrée dans l'ordre de réception. Ensuite, parallel
divise le <stdin>
en morceaux de taille 10 Mo, et pour chaque segment, il passe par nl -n rz
où il ajoute simplement un nombre justifié (voir nl --help
pour plus de détails). Les options --pipe
indique à parallel
de séparer <stdin>
en plusieurs tâches et -- block
spécifie la taille des blocs. L'option -k
spécifie que le classement doit être maintenu.
Votre résultat final devrait ressembler à quelque chose comme
000001 1 <data>
000002 2 <data>
000003 3 <data>
000004 4 <data>
000005 5 <data>
...
000587 552409 <data>
000588 552410 <data>
000589 552411 <data>
000590 552412 <data>
000591 552413 <data>
Mon fichier original comportait 552 413 lignes. La première colonne représente les travaux parallèles et la deuxième colonne représente la numérotation de la ligne d'origine transmise en parallel
par blocs. Vous devez noter que l'ordre dans la deuxième colonne (et le reste du fichier) est conservé.