Comment puis-je exécuter mogrify, mais préfixer le nom du fichier?

3

J'ai 300k + jpg dans le même répertoire. Les fichiers sont comme:

/covers    
0788862281217.jpg
0788863155104.jpg
7888311516341.jpg
7888370920479.jpg
7888497074277.jpg

J'ai besoin de redimensionner par lots en enregistrant les images redimensionnées dans le même répertoire avec un préfixe th_ dans le nom de fichier comme

th_0788862281217.jpg
th_0788863155104.jpg
th_7888311516341.jpg
th_7888370920479.jpg
th_7888497074277.jpg

tout à l'intérieur /covers

Ce qui suit fonctionne mais écrase les fichiers source

$ find thumbs -type f -name "*.jpg" | xargs mogrify -resize 75x75

je dois donc copier toutes les images dans un nouveau répertoire (/ covers / thumbs), puis exécuter le lot, puis déplacer tous les fichiers dans / covers

Gabriele
la source

Réponses:

7

Du manuel:

Mogrify écrase le fichier image d'origine, alors que convert (1) écrit dans un fichier image différent.

Tu peux faire:

find ./covers -type f -name '*.jpg' -execdir convert {} -resize 75x75 th_{} \;

Ce sera probablement le plus efficace si vous avez un grand nombre de fichiers.

En général, pour diverses raisons, il est plutôt déconseillé de diriger la sortie de findsur xargs, à moins que vous n'utilisiez le modèle suivant, que les findvariantes GNU et BSD prennent en charge:find … -print0 | xargs -0 …


Si vous souhaitez utiliser des commandes shell uniquement, vous pouvez parcourir les fichiers de la manière suivante:

for image in ./covers/*.jpg; do convert "$image" -resize 75x75 "$(dirname $image)/th_$(basename $image)"; done

C'est le plus simple (et le plus sûr) que vous puissiez obtenir, sans avoir recours à des commandes externes. Cependant, vous devrez diviser chemin et nom de fichier, puis insérer le préfixe entre les deux. Si vous êtes déjà dans le même dossier, c'est beaucoup plus facile:

for i in *.jpg; do convert "$i" -resize 75x75 "th_$i"; done

Une solution universelle et plus courte avec Zsh:

for i (./covers/*.jpg) convert "$i" -resize 75x75 "${i:h}/th_${i:t}"    
slhck
la source
salut! Mes fichiers ne sont PAS dans le dossier / thumbs mais dans / covers. Je suppose donc que la ligne de commande deviendra: for image in covers / *. Jpg; convertir "$ image" - redimensionner 75x75 "e _ $ (nom de base $ image)"; done Cela sera-t-il sauvegardé dans le même répertoire que les fichiers maîtres? Correct? Tnx!
Gabriele
J'ai essayé avec un exemple de répertoire / fichiers. Cela n'a pas fonctionné
Gabriele
Désolé, mauvais dossier là-bas. Voir ma dernière mise à jour. Si vous souhaitez que la commande fonctionne avec un dossier quelconque, vous devez diviser le chemin entre dirnameet basenameet y insérer le préfixe. Ce qui suit serait plus facile, si vous êtes déjà dans le dossier: for i in *.jpg; do convert "$i" -resize 75x75 "th_$i"; done.
Slhck
Le test avec 3 images a été un succès. Je vais l'exécuter dans le répertoire principal avec plus de 300 000 fichiers et je reviendrai ici. Merci slhck!
Gabriele
1
Si votre liste d'arguments est trop longue (à cause des fichiers de plus de 300 Ko), essayez la variante findavec execdirlaquelle j'ai ajouté à ma réponse ci-dessus.
Slhck