2010-09-28 9 views
22

J'ai des milliers de fichiers png que j'aime faire plus petit avec pngcrush. J'ai un simple travail find .. -exec, mais c'est séquentiel. Ma machine a beaucoup de ressources et je ferais cela en parallèle.Traitement parallèle en bash?

L'opération à effectuer sur chaque .png est:

pngcrush input output && mv output input 

je peux Idéalement spécifier le nombre maximum d'opérations parallèles.

Y a-t-il un moyen de le faire avec bash et/ou d'autres helpers shell? Je suis Ubuntu ou Debian.

Répondre

35

Vous pouvez utiliser xargs pour exécuter plusieurs processus en parallèle:

find /path -print0 | xargs -0 -n 1 -P <nr_procs> sh -c 'pngcrush $1 temp.$$ && mv temp.$$ $1' sh 

xargs lira la liste des fichiers produits par find (séparés par 0 caractères (-0)) et exécutez la commande fournie (sh -c '...' sh) avec un paramètre à la fois (-n 1). xargs exécutera <nr_procs> (-P <nr_procs>) en parallèle.

+0

«$ 1» n'est pas rempli, j'ai aussi essayé avec un exemple minimal sans chance. xargs est 4.4.0, une idée? – mark

+0

J'ai oublié de spécifier la valeur pour 0 $. Devrait être réparé maintenant. –

+0

confirmé, fonctionne! Pourriez-vous éditer votre réponse? – mark

11

Vous pouvez utiliser des solutions sur mesure find/xargs (voir la réponse de Bart Sas), mais quand les choses deviennent plus complexes que vous avez deux options au moins-puissants:

  1. parallel (paquet de moreutils)
  2. GNU parallel
+2

Paquets Deb et RPM: https://build.opensuse.org/package/show?package=parallel&project=home%3Atange –

+4

Je recommande vivement GNU parallel sur la version de moreutils. C'est beaucoup plus flexible. –

+3

find/path -print0 | parallel -0 pngcrush {} {.}. temp '&&' mv {.}. temp {} –