IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Shell et commandes GNU Discussion :

find et -exec


Sujet :

Shell et commandes GNU

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau candidat au Club
    Homme Profil pro
    Consultant communication & réseaux
    Inscrit en
    Février 2017
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Consultant communication & réseaux

    Informations forums :
    Inscription : Février 2017
    Messages : 2
    Par défaut find et -exec
    Bonjour

    Je souhaite faire un mv de toutes les photos que j'ai dans un $HOME vers un directory type bkp_Photos.

    J'ai essayé la commande suivante sans grande réussite. Je n'arrive pas à comprendre pourquoi elle ne fonctionne pas.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    cd ~
    find . -name "*.jpeg" -exec mv {} ./bkp_Photos \;
    Merci pour votre aide.

    dbox911.

  2. #2
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 658
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 658
    Par défaut
    Bonjour,

    « ça marche pas » : les images ne sont pas déplacées ?
    est-ce qu'il y a un message d'erreur ?
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  3. #3
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 102
    Par défaut
    Citation Envoyé par dbox911 Voir le message
    J'ai essayé la commande suivante sans grande réussite. Je n'arrive pas à comprendre pourquoi elle ne fonctionne pas.
    Ma boule de cristal étant actuellement chez le réparateur, difficile de deviner ce qui ne va pas...


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    cd ~
    find . -name "*.jpeg" -exec mv {} ./bkp_Photos \;
    A priori, la commande n'a pas l'air trop mal! Avec juste 2-3 bémols...

    Est-ce que le répertoire ./bkp_Photos existait bien avant le premier lancement?
    Que répond ls -ld ./bkp_Photos, voire file ./bkp_Photos?
    Car, si le répertoire n'existait pas avant le premier lancement de la commande, alors, à cause du ';', le premier "mv" va déplacer et renommer la première photo en ./bkp_PhotosDe plus, s'il y a déjà des photos dans ./bkp_Photos, il est probable que "find" va les trouver et que "mv" ne va pas être d'accord de devoir les déplacer où elles sont déjà... (quelle idée d'avoir une commande pour 2 actions différentes (déplacer et renommer)!)

    Et j'aurais soit utilisé '+' soit mis un '/' au répertoire (soit les deux):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find . -name "*.jpeg" -exec mv {} ./bkp_Photos/ '+' # OOPS!


    EDIT:
    Attention, ça ne marche pas avec '+' (voir messages suivants)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find . -name "*.jpeg" -exec mv {} ./bkp_Photos/ ';'

  4. #4
    Nouveau candidat au Club
    Homme Profil pro
    Consultant communication & réseaux
    Inscrit en
    Février 2017
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Consultant communication & réseaux

    Informations forums :
    Inscription : Février 2017
    Messages : 2
    Par défaut
    Bonsoir

    Je vous remercie pour vos retours. J'ai refait le test en m'assurant que les directories étaient bien présents et en me placant dans un directory different. Tout fonctionne.
    Je garde l'idée du '+' et du '/'

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    cd /home/user1
    find ./photo -name "*.jpeg" -exec mv {} ./bkp_Photos/ '+'

    Merci pour votre aide et support
    Dbox911.

  5. #5
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 102
    Par défaut
    Citation Envoyé par dbox911 Voir le message
    J'ai refait le test en m'assurant que les directories étaient bien présents et en me placant dans un directory different. Tout fonctionne.
    Bonne nouvelle!

    et pense au bouton

    Je garde l'idée du '+' et du '/'
    Euh... garde l'idée du '/' mais abandonne celle du '+'...

  6. #6
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 658
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 658
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    -exec mv --target-directory=DIRECTORY {} +
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  7. #7
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mai 2013
    Messages
    153
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Mai 2013
    Messages : 153
    Par défaut
    Pour varier, zsh :
    Avec le globbing récursif, il n'y a pas besoin de find. En plus, il n'y a pas de problèmes si des noms des fichiers contiennent des espaces.

  8. #8
    Modérateur
    Avatar de jlliagre
    Homme Profil pro
    Ingénieur support avancé & développement
    Inscrit en
    Juin 2007
    Messages
    2 695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur support avancé & développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 695
    Par défaut
    Citation Envoyé par jack-ft Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find . -name "*.jpeg" -exec mv {} ./bkp_Photos/ '+'
    Hmm, tu es sûr ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ find . -name "*.jpeg" -exec mv {} ./bkp_Photos/ '+'
    find: paramètre manquant pour «*-exec*»
    $ find --version | head -1                           
    find (GNU findutils) 4.7.0-git

  9. #9
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 102
    Par défaut
    Citation Envoyé par jlliagre Voir le message
    Hmm, tu es sûr ?
    Ben... non...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ find . -name "*.jpeg" -exec mv {} ./bkp_Photos/ '+'
    find: paramètre manquant pour «*-exec*»
    $ find --version | head -1                           
    find (GNU findutils) 4.7.0-git
    J'ai toujours beaucoup de mal à faire marcher _mon_ find avec '+' alors qu'avec ';' y a pas de problème
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    $ find . -name "*.jpeg" -exec echo mv {} ./bkp_Photos/ '+'
    find: -exec: no terminating ";" or "+"
     
    $ find . -name "*.jpeg" -exec echo mv {} ./bkp_Photos/ +
    find: -exec: no terminating ";" or "+"
     
    $ find . -name "*.jpeg" -exec echo mv {} ./bkp_Photos/ \+
    find: -exec: no terminating ";" or "+"
     
    $ find . -name "*.jpeg" -exec echo mv {} ./bkp_Photos/ \;
    mv foo.jpeg ./bkp_Photos/
    mv bar.jpeg ./bkp_Photos/
     
    $ find --version
    find: illegal option -- -
    usage: find [-H | -L | -P] [-EXdsx] [-f path] path ... [expression]
           find [-H | -L | -P] [-EXdsx] -f path [path ...] [expression]
     
    $ uname -a
    Darwin MBPR15-jack 15.6.0 Darwin Kernel Version 15.6.0: Mon Jan  9 23:07:29 PST 2017; root:xnu-3248.60.11.2.1~1/RELEASE_X86_64 x86_64
    Hum... je crois que j'ai trouvé (rtfm...):
    $ man find
    -exec utility [argument ...] {} +
    Same as -exec, except that ``{}'' is replaced with as many pathnames as possible for each invocation of utility. This behaviour is similar to that of xargs(1).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ find . -name "*.jpeg" -exec echo mv {} +
    mv foo.jpeg bar.jpeg
    Manifestement, il faut que "{}" soit juste avant "+", ce qui est le cas, par exemple, pour un "grep" où l'on veut voir le nom des fichiers:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $ find . -name "*.txt" -exec grep "chaine" {} +
    Mais apparemment il ne peut pas expanser "{}" avec la liste des fichiers s'il y a autre chose derrière.

    Je ne vois donc pas comment faire un mv *.jpeg ./bkp_Photos/ en un seul "mv" avec "find"...

    Mais la solution avec / et ';' tient toujours:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find . -name "*.jpeg" -exec mv {} ./bkp_Photos/ ';'

  10. #10
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par jack-ft Voir le message
    J'ai toujours beaucoup de mal à faire marcher _mon_ find avec '+' alors qu'avec ';' y a pas de problème
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    $ find . -name "*.jpeg" -exec echo mv {} ./bkp_Photos/ '+'
    find: -exec: no terminating ";" or "+"
     
    $ find . -name "*.jpeg" -exec echo mv {} ./bkp_Photos/ +
    find: -exec: no terminating ";" or "+"
     
    $ find . -name "*.jpeg" -exec echo mv {} ./bkp_Photos/ \+
    find: -exec: no terminating ";" or "+"
     
    $ find . -name "*.jpeg" -exec echo mv {} ./bkp_Photos/ \;
    Bonjour

    Manifestement tu ne piges pas trop pourquoi le "+", pourquoi le ";" et pourquoi le "\"...

    Quand tu lances find -exec, tu es sensé mettre une commande après le -exec. Mais une commande peut avoir plusieurs syntaxes. Ca peut être commande, ou bien commande arg1, pu bien commande arg1 arg2. Bref le find ne connait pas à l'avance le format de ta commande.
    Il te faut donc donner une indication au find sur la commande et notamment l'endroit où elle se termine. Parce que si tu tapes find . -type f -exec ls {} -print on ne peut pas, à priori, savoir si le -print est une option du find ou un argument de la commande ls.
    Cette indication est donc donnée par le caractère ";" ou bien par le caractère "+". Le ";" demande au exec d'exécuter la commande pour chaque fichier trouvé pris un par un ; et le "+" demande au exec d'exécuter la commande pour un maximum de fichiers d'un coup.
    Cependant le ";" est aussi un méta-caractère du shell. Si on veut que le find le reçoive tel quel, il faut alors le protéger lors de l'appel donc un backslash (ou alors des quotes). En revanche, le "+" n'est pas un méta-caractère donc pas besoin de quoi que ce soit.

    Il reste un détail avec le "+" car ça demande au -exec d'intégrer tous les fichiers d'un coup à la commande. Mais dans ce type d'écriture -exec mv {} ./bkp_Photos, comment le -exec va insérer les fichiers au mv ? Si par exemple il y en a 3 "fic1" "fic2" et "fic3", va-t-il l'insérer de cette façon: mv fic1 fic2 fic3 ./bkp_Photos (ce qui est correct) ou bien plutôt mv fic1 ./bkp_Photos fic2 fic3 (ce qui ne correspond à plus rien de logique) ?
    C'est pourquoi le "+" ne peut se mettre que pour des commandes qui n'ont pas à recevoir d'autres arguments que le ou les fichiers à traiter (ex: ls, rm, md5sum, echo, etc...).

    Exemples possibles
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ find . -name "*.jpeg" -exec mv {} ./bkp_Photos/ \;
    $ find . -name "*.jpeg" -exec mv {} ./bkp_Photos/ ';'
    $ find . -name "*.jpeg" -exec ls -l {} \;
    $ find . -name "*.jpeg" -exec ls -l {} +
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  11. #11
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 102
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Manifestement tu ne piges pas trop pourquoi le "+", pourquoi le ";" et pourquoi le "\"...
    Si si, j'ai bien compris!

    C'était juste que, avant de lire le "man", j'imaginais que "{}" s'expansait en la liste des fichiers concernés et que j'étais "enduit" d'erreur par le message de "find":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ find . -name "*.jpeg" -exec echo mv {} ./bkp_Photos/ '+'
    find: -exec: no terminating ";" or "+"
    Quand je lisais ce message d'erreur, j'étais pour le moins perplexe et confus!
    Pourquoi me dit-il que le "-exec" du "find" n'est pas terminé par ";" ou "+" alors qu'il est clair que si???
    La confusion vient aussi en partie du fait que c'est exactement le même message que lorsqu'on "oublie" de quoter le ";":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ find . -name "*.jpeg" -exec echo mv {} ./bkp_Photos/ ;
    find: -exec: no terminating ";" or "+"
    Mais merci quand même pour tes explications (qui ont au moins le mérite d'être claires)!

    [HS]
    Pour la petite histoire, je n'ai réellement compris que récemment (probablement sur ce forum, il y a moins d'une décennie) le fonctionnement de l'option "-exec" de "find" avec le terminateur "\;" que j'ai bien utilisé, puis encore plus récemment (probablement sur ce forum, il y a moins d'un lustre) celui du terminateur "+". Comme je le disais plus haut, c'est bien pratique pour faire apparaître le nom des fichiers lors de l'utilisation d'un "-exec grep", surtout si l'on ne connait pas l'option "-H" de "grep"...
    [/HS]

Discussions similaires

  1. [OS X] [SH] Utilisation de find et -exec
    Par medmaysais dans le forum Shell et commandes POSIX
    Réponses: 2
    Dernier message: 13/03/2016, 21h11
  2. Utiliser exec plusieurs fois dans find
    Par Tex-Twil dans le forum Shell et commandes GNU
    Réponses: 0
    Dernier message: 12/03/2008, 14h49
  3. utilisation de l'option -exec de find
    Par panach91 dans le forum Shell et commandes GNU
    Réponses: 10
    Dernier message: 17/01/2008, 11h34
  4. verifier la suppression dans le exec du find
    Par decksroy dans le forum Linux
    Réponses: 4
    Dernier message: 04/12/2007, 11h45
  5. [find] Problème avec -exec
    Par kromartien dans le forum Shell et commandes GNU
    Réponses: 9
    Dernier message: 06/11/2007, 17h09

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo