Comme la première version tient sur une seule ligne, le Shell doit analyser l'ensemble avant de l'exécuter. Mais **/*.@(jpg|jpeg|png|gif)
n'est valable que pour la syntaxe après shopt -s extglob
a été exécuté ... c'est-à-dire une fois que la ligne est passée par la phase d'analyse.
Si cela doit être une réplique, je ne connais pas de bonne façon de le faire. Mais vous devriez pouvoir tricher en utilisant une expansion d'accolade au lieu d'un glob étendu, et en modifiant le test pour les fichiers :
shopt -s globstar && for f in **/*.{jpg,jpeg,png,gif}; do [[ -f "$f" && ! -f "$f.webp" ]] && cwebp -quiet -q 80 "$f" -o "$f.webp"; done
Il convient de noter que, dans la mesure où globstar
prend effet lorsque le caractère générique est développé, et non lors de la première passe d'analyse, ce problème ne s'applique pas à lui.
Explication : bash développe les accolades avant d'étendre les caractères génériques, donc
for f in **/*.{jpg,jpeg,png,gif};
s'étend à
for f in **/*.jpg **/*.jpeg **/*.png **/*.gif;
...puis chacun de ces motifs est développé séparément. Il y a un problème potentiel : s'il n'y a pas au moins un fichier correspondant à chacun des quatre motifs, le(s) motif(s) non correspondant(s) sera(ont) laissé(s) tel(s) qu'il(s) est(sont) un(s) espace(s) vide(s).
Par exemple, s'il n'y a que des fichiers .jpg et .png, la liste entièrement développée pourrait contenir quelque chose comme ceci :
path/to/image1.jpg
path/to/image2.jpg
**/*.jpeg
path/to/image3.png
**/*.gif
...et il continuera à exécuter la boucle avec chacun d'entre eux, y compris **/*.jpeg
y **/*.gif
. C'est pourquoi j'ai dû modifier le test à l'intérieur de la boucle en
[[ -f "$f" && ! -f "$f.webp" ]] && cwebp ...
En -f "$f"
échouera sur les caractères génériques non développés et l'empêchera d'essayer de créer des versions webp de fichiers inexistants. Vous pouvez également utiliser ceci, qui est plus proche du test original :
[[ ! -f "$f" || -f "$f.webp" ]] || cwebp ...
Mais je pensais que c'était plus intuitif sous l'autre forme.
BTW, une autre solution possible pour résoudre le problème des caractères génériques non appariés est d'ajouter shopt -s nullglob
ce qui a pour effet de faire disparaître les éléments non appariés.