2009-11-16 3 views
1

J'écris un script pour redimensionner les images par lots. A l'origine, j'appliquais une opération for file in $(ls $1), mais je voudrais pouvoir utiliser la globbing, donc je regarde quelque chose de plus comme for file in $(echo $1). Le problème est que dotglob peut ou ne peut pas être activé, donc echo * peut renvoyer des fichiers cachés (notamment, .DS_Store), ce qui provoque convert pour lancer une erreur et arrêter le script. Je voudrais que le comportement par défaut de la commande soit que si je cd dans un répertoire plein d'images et exécute resize * 400x400 jpg, toutes les images seront redimensionnées à l'exclusion fichiers cachés, indépendamment du fait que dotglob est activé.Filtrer les fichiers cachés avec Bash (pour le script de redimensionnement d'image par lots)

Ainsi, dans le code pseudo, Je cherche:

for file in $(echo $1 | [filter-hidden-files]) 

Voici mon script avec le comportement plus . Mettra à jour avec un nouveau comportement quand je trouve une solution:

# !/bin/bash 

# resize [folder] [sizeXxsizeY] [outputformat] 
# if [outputformat] is omitted, the input file format is assumed 

for file in $(ls $1) 
do 
    IMGNAME=$(echo "$file" | cut -d'.' -f1) 
    if test -z $3 
    then 
     EXTENSION=$(echo "$file" | cut -d'.' -f2) 
     convert $1/$file -resize $2 -quality 100 $1/$IMGNAME-$2.$EXTENSION 
     echo "$file => $IMGNAME-$2.$EXTENSION" 
    else 
     convert $1/$file -resize $2 -quality 100 $1/$IMGNAME-$2.$3 
     echo "$file => $IMGNAME-$2.$3" 
    fi 
done 

Voici le script en cours :

# !/bin/bash 

# resize [pattern] [sizeXxsizeY] [outputformat] 
# if [outputformat] is omitted, the input file format is assumed 

for file in $(echo $1) 
do 
     IMGNAME=$(echo "$file" | cut -d'.' -f1) 
     if test -z $3 && if test -f $3 
     then 
      EXTENSION=$(echo "$file" | cut -d'.' -f2) 
      convert $file -resize $2 -quality 100 $IMGNAME-$2.$EXTENSION 
      echo "$file => $IMGNAME-$2.$EXTENSION" 
     else 
      convert $file -resize $2 -quality 100 $IMGNAME-$2.$3 
      echo "$file => $IMGNAME-$2.$3" 
     fi 
done 

Compte tenu de la commande resize * 400x400, convertir renvoie une erreur car il ne peut pas traiter .DS_Store (un fichier caché résidant dans chaque fichier sur un système OSX). Comme je ne traiterai jamais d'images cachées, je voudrais les filtrer automatiquement. J'ai essayé de le faire avec grep ou trouver, mais je ne l'ai pas encore compris.

Nouveau script va ici:

for file in $(echo $1) 
do 
+0

Vous pouvez éliminer l'appel à l'extérieur 'cut':' IMGNAME = $ {fichier # # *.} ' –

Répondre

1

Il y a une option shell dotglob qui décide si les fichiers commençant par . sont inclus lorsque les jokers. Vous pouvez vérifier si tel est le cas avec

shopt dotglob 

Vous désactiver pouvez également explicitement dans votre script:

#!/bin/bash 

shopt -u dotglob 

for file in $1/*; do 
    ... 
done 
+0

Pour une raison quelconque, essayer de définir le paramètre dotglob dans le script ne fonctionne pas. Si je lance shopt -u dotglob dans le shell, alors echo * a le paramètre désiré, mais si je mets la ligne dans le script et l'exécute, cela ne change pas le paramètre. – terrace

1

que vous obtenez une liste de fichiers en $ * vous pouvez les vérifier un par un

for i in $* 
do 
    expr $i : '^\..*' > /dev/null && continue 
    # process file 
done 
+0

Gardez à l'esprit que je ne veux pas que le script agisse automatiquement sur tous les fichiers du répertoire courant. Je veux être capable d'utiliser tous les globbers, donc le test doit être de la forme "echo $ 1 | [filter]", sauf si echo peut faire le filtre ou si je n'ai pas besoin d'écho du tout. Il doit travailler avec des paramètres de position. – terrace

+0

désolé, ne l'ai pas compris, va mettre à jour la solution – catwalk

+0

$ * retourne tous les paramètres de position, y compris ma dimension de l'image et les paramètres de format de sortie. – terrace

1

Il n'est pas nécessaire d'utiliser ls avec une boucle for, la plupart du temps c'est inutile. la boucle for avec * ne renvoie pas non plus de fichiers cachés, à moins que vous ne le spécifiiez spécifiquement. Pour afficher les fichiers cachés,

for files in .* 
do 
echo $files 
done 
+0

Rappelez-vous, je cherche à utiliser le paramètre positionnel $ 1 comme argument pour que je puisse utiliser n'importe quel globber – terrace

+0

shopt dotglob réglé sur "yes", * retournera les fichiers cachés Malheureusement, il semble que je ne puisse pas changer ce paramètre avec le script – terrace

3

Je suggère de changer la ligne de commande de votre script resize * 400x400-resize 400x400 *, le script serait plus comme les outils standard unix de cette façon (grep, sed, ln, etc.). Vous n'auriez pas à désactiver l'option dotglob dans votre script (ce qui est préférable car c'est à l'utilisateur du script s'il veut que les fichiers cachés soient globalisés ou non).

Votre script ressemblerait à quelque chose comme ceci:

#!/bin/bash 

OUTPUTFORMAT=$1 
# Remove original $1 from the list of arguments 
shift 

for i in "[email protected]" 
do 
    # Use $OUTPUTFORMAT here 
    etc.... 

Si vous ne voulez pas changer la ligne de commande pour votre script.Vous pouvez essayer de régler GLOBIGNORE

export GLOBIGNORE=".*" 

Ou si extglob est défini, vous pouvez essayer fichier englobement comme ceci:

echo !(.*) 
+0

Je voulais que la syntaxe soit cohérente avec la commande convert, qui prend les commandes comme ceci: convert [input file ] [options] [fichier de sortie], mais je vais prendre votre avis pour l'instant – terrace

+0

Aussi, si je fais cela, je ne suis pas sûr de savoir comment je peux faire en sorte que le format de sortie peut être omis – terrace

+0

Je suppose que 400x400 est le format de sortie J'ai édité mon script pour le rendre plus clair comment sauter ceci –

Questions connexes