Bonjour à tous,
j'ai récemment été confronté au problème suivant : j'ai un vieux disque dur qui contient des photos de ci de là, je souhaitais toutes les récupérer rapidement sans avoir à explorer manuellement tous les (nombreux) sous-répertoires.
J'ai trouvé une solution avec la commande find de Linux et je me suis dit que j'allais partager ça avec vous 🙂
N'hésitez pas si vous avez des remarques ou des commentaires !
Dans la suite, je suppose que mes images peuvent avoir l'une des extensions suivantes : jpg, jpeg, JPG, JPEG
Je suppose que le répertoire racine où chercher mes images s'appelle "/chemin/a/traiter/" et le répertoire où copier mes images s'appelle "/chemin/de/backup/"
Voici ma commande
$ find -E /chemin/a/traiter/ -iregex '.*\.jpe?g' -exec cp {} /chemin/de/backup/ \;
Explications :
1) Construction de la regexp
Je veux un pattern qui matche les noms de fichier se terminant par .jpg, .jpeg, .JPG ou .JPEG
Ma regex en ERE (Extended Regular Expression) s'écrit : .*.jpe?g
Cela signifie de gauche à droite :
- n'importe quelle séquence de caractère : .*
- suivi d'un point : .
- suivi des caractères j et p : jp
- suivi d'un éventuel e : e?
- suivi d'un g
2) Branchement de la regexp dans le find
Cette regexp utilisant le méta-caractère '?' qui est défini dans les ERE, il faut que je dise implicitement à find d'utiliser ces types de regex, c'est le rôle de l'option -E
Au final on a donc :
$ find -E /chemin/a/traiter/ -iregex '.*\.jpe?g'
L'option -iregex remplace ici l'habituel -name et permet d'utiliser une regexp et d'être insensible à la casse. Remarquons au passage que toto.jPeG sera également retenu par le filtre, mais ça n'est pas bien grave...
A ce niveau de la commande, nous sommes en mesure de lister l'ensemble des photos présentes dans le répertoire à traiter. Il nous reste à copier ces fichiers vers le répertoire cible.
3) Copier des photos vers le répertoire cible
C'ets le rôle de l'option -exec dont le prototype est le suivant :
$ find <blablabla> -exec ma_commande {} \;
Ici la séquence {} sera remplacée itérativement par chaque valeur trouvée dans find.
Ainsi si mon find trouve 3 images a.jpg, b.JPG et c.jpeg, il lancera ma_commande 3 fois :
$ ma_commande a.jpg
$ ma_commande b.JPG
$ ma_commande c.jpeg
La séquence \; sert à marquer la fin de l'instruction -exec. A noter que si on remplace \; par + alors ma_commande est lancée une seule fois avec tous les arguments à la suite. Dans notre exemple, ça donnerait donc
$ ma_commande a.jpg b.JPG c.jpeg
Ici c'est bien le comportement itératif qui nous intéresse. On remplace ma_commande par cp et on spécifie le répertoire de sortie, ce qui donne notre commande finale :
$ find -E /chemin/a/traiter/ -iregex '.*\.jpe?g' -exec cp {} /chemin/de/backup/ \;
L'inconvénient de cette solution est qu'on perd *complètement* l'arborescence de nos photos : tout est écrit en plat. Mais au moins on est sûr d'être exhaustif 🙂
Bonne aprem et à bientôt 🙂
Donut.