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?
Vérification si l'input est correcte
if [ $# != 2 ]; then echo "Usage: phar image_path archive_path" && exit; fi
Cela va créer un directory de destination s'il n'existe pas
mkdir -p $2
Déclaration qui trouve et copy et ajoute les suffixes nécessaires aux files
find $1 -iname IMG_[0-9][0-9][0-9][0-9].JPG -exec cp -b --suffix=.JPG {} $2 \; echo complete!
Vérifiez et supprimez l'instruction en double. Il comparera le MD5 de chaque file.
shopt -s nullglob for file in "$2"/* do md5sum=$(md5sum < "$file") echo "-- Found: $file ($md5sum)" for duplicate in "$2"/* #loop to find/remove duplicates do [ "$file" = "$duplicate" ] && continue #comparison of 2 files [ "$md5sum" = "$(md5sum < "$duplicate")" ] && rm -v "$duplicate" #removal of duplicates done done
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 \;