Filtrage des images en fonction du nom du file, pourquoi?

Lors du filtrage des images en utilisant le code ci-dessous, j'ai aussi besoin de filterr les files.

Par exemple, IMG_0079.JPG.JPG , lors de l'exécution du code ci-dessous, il permet aux files avec .JPG supplémentaires d'être filtrés, et je n'arrive pas à découvrir pourquoi?

Si je lis ceci correctement, votre problème se trouve ici:

 find $1 -iname IMG_[0-9][0-9][0-9][0-9].JPG 

Cela ne trouve jamais les files .JPG.JPG en premier lieu. Regardez:

 mkdir JPG for n in 9 8 7 6 5 4 3 2 1 do touch ./JPG/IMG_000${n}.JPG done find ./JPG -iname IMG_[0-9][0-9][0-9][0-9].JPG ###OUTPUT### ./JPG/IMG_0001.JPG ./JPG/IMG_0002.JPG ./JPG/IMG_0003.JPG ./JPG/IMG_0004.JPG ./JPG/IMG_0005.JPG ./JPG/IMG_0006.JPG ./JPG/IMG_0007.JPG ./JPG/IMG_0008.JPG ./JPG/IMG_0009.JPG 

Alors maintenant je vais …

 for f in ./JPG/* ; do touch ${f}.JPG ; done && ls ./JPG IMG_0001.JPG IMG_0003.JPG.JPG IMG_0006.JPG IMG_0008.JPG.JPG IMG_0001.JPG.JPG IMG_0004.JPG IMG_0006.JPG.JPG IMG_0009.JPG IMG_0002.JPG IMG_0004.JPG.JPG IMG_0007.JPG IMG_0009.JPG.JPG IMG_0002.JPG.JPG IMG_0005.JPG IMG_0007.JPG.JPG IMG_0003.JPG IMG_0005.JPG.JPG IMG_0008.JPG 

Voyons ce que la find nous montre maintenant:

 find ./JPG -iname IMG_[0-9][0-9][0-9][0-9].JPG ###OUTPUT### ./JPG/IMG_0001.JPG ./JPG/IMG_0002.JPG ./JPG/IMG_0003.JPG ./JPG/IMG_0004.JPG ./JPG/IMG_0005.JPG ./JPG/IMG_0006.JPG ./JPG/IMG_0007.JPG ./JPG/IMG_0008.JPG ./JPG/IMG_0009.JPG 

Donc, vous voyez, parce que mes .JPG.JPG files .JPG.JPG ne se terminent pas par la string [0-9]{4}.JPG find ne les affiche jamais en premier lieu. L'ajout d'un \* à la fin de cette -iname search -iname pourrait fonctionner mieux pour vous.

Pourtant, comme l'autre réponse mentionne, un autre problème est votre globs shell. Par exemple:

 sh -cx 'cd ./JPG ; find . -iname IMG_[0-9][0-9][0-9][0-9].JPG' + cd ./JPG + find . -iname IMG_0001.JPG IMG_0002.JPG IMG_0003.JPG IMG_0004.JPG IMG_0005.JPG IMG_0006.JPG IMG_0007.JPG IMG_0008.JPG IMG_0009.JPG find: paths must precede expression: IMG_0002.JPG Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression] 

Tu vois? Si le shell peut le faire, [glob] sur les crochets sans guillemets que vous avez avant même de remettre la string de command à find . Il devrait probablement ressembler plus à ceci:

 find "$1" -iname 'IMG_[0-9][0-9][0-9][0-9].JPG*' 

Et en ce qui concerne le dernier bit, vous pourriez ne pas avoir besoin de boucle récursive autant. Je pense – aussi longtime que vous ne cherchez qu'à supprimer vieux cp --suffix=.JPG -b – b ackups – cela pourrait faire un rlocation pratique pour tout de shopt... sur:

 ( dir=$2 set -- "${dir}"/*[0-9].??? while [ -e "$1" ] do cmp "$1" "${1}.JPG" && rm -v "${1}.JPG" 2>&1 shift ; done ) 2>/dev/null 

Bien que, certes, cela pourrait être optimisé beaucoup avec une sorte de boucle récursive comme:

 ( dir=$2 set -- "${dir}"/*[0-9].??? while [ -e "$1" ] do until [ -e "${1}.JPG" ] do shift || break; done cmp "$1" "${1}.JPG" && rm -v "${1}.JPG" 2>&1 ${1+shift} ; done ) 2>/dev/null 

Je dis en quelque sorte parce while loops while et until fonctionnent sur le même set de parameters et ne testent même jamais le même file deux fois afin qu'elles ne récurrentent pas exactement même si elles sont nestedes. Quoi qu'il en soit, l'optimization consiste à exec aucun autre process until cela until nécessaire et à ne countr que sur les architectures shell autant que possible.

La boucle for vous avez mentionnée est une erreur pour moi. Mais cela fonctionne très bien quand j'utilise le caractère d'échappement pour les crochets. Donc ma boucle for serait comme ça:

 find $1 -iname IMG_\\[0-9\\]\\[0-9\\]\\[0-9\\]\\[0-9\\].JPG -exec cp -b --suffix=.JPG {} $2 \;