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 :

Copier des fichiers en conservant leur chemin


Sujet :

Shell et commandes GNU

  1. #1
    Membre du Club
    Inscrit en
    Mars 2008
    Messages
    80
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 80
    Points : 41
    Points
    41
    Par défaut Copier des fichiers en conservant leur chemin
    Bonjour,

    Je voudrais copier une série de ficher sélectionnés par un filtre dans un répertoire cible, tout en conservant leur chemin. Quelque chose comme cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    find -iname "*Copie*" -exec mv '{}' ~/backup/
    Le problème avec cette commande, c'est que si j'ai deux fichiers du même nom dans un dossier différent, j'obtiens un conflit. Par exemple si ma source est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ~/bureau/doss1/fichier
    ~/bureau/doss1/fichierCopie
    ~/bureau/doss2/fichier
    ~/bureau/doss2/fichierCopie
    Je voudrais obtenir
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ~/bureau/doss1/fichier
    ~/bureau/doss2/fichier
    ~/backup/doss1/fichierCopie
    ~/backup/doss2/fichierCopie
    Merci de votre aide,
    Thibaud.

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 552
    Points : 19 392
    Points
    19 392
    Par défaut
    Bonjour,

    je ne me souviens pas que find puisse faire de telles choses tout seul.
    -printf peut manipuler les données affichées, mais -exec n'en tient pas compte.

    regarde ici
    ...
    ?
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  3. #3
    Expert éminent sénior Avatar de frp31
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Juillet 2006
    Messages
    5 196
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juillet 2006
    Messages : 5 196
    Points : 12 264
    Points
    12 264
    Par défaut
    Citation Envoyé par thibaud74 Voir le message
    Bonjour,

    Je voudrais copier une série de ficher sélectionnés par un filtre dans un répertoire cible, tout en conservant leur chemin. Quelque chose comme cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    find -iname "*Copie*" -exec mv '{}' ~/backup/
    Le problème avec cette commande, c'est que si j'ai deux fichiers du même nom dans un dossier différent, j'obtiens un conflit. Par exemple si ma source est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ~/bureau/doss1/fichier
    ~/bureau/doss1/fichierCopie
    ~/bureau/doss2/fichier
    ~/bureau/doss2/fichierCopie
    Je voudrais obtenir
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ~/bureau/doss1/fichier
    ~/bureau/doss2/fichier
    ~/backup/doss1/fichierCopie
    ~/backup/doss2/fichierCopie
    Merci de votre aide,
    Thibaud.
    c'est pour ça qu'il faut tjrs horodater les fichiers DESTINATION pour distinguer
    genre ~/backup/toto.2012112708183010

    ça empêche ce genre de problèmes. voir utiliser le pid de la commande cp si c'est une boucle par itération en plus de la date pour différentier encore plus.
    exemple ~/backup/toto.17234.2012112708183010
    ce qui évite que l'action trop rapide utiliser la meme seconde+dizième (ici 3010)

  4. #4
    Expert confirmé
    Avatar de Loceka
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    2 276
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 2 276
    Points : 4 845
    Points
    4 845
    Par défaut
    Perso, pour ce genre de traitements, je fais un script intermédiaire que j'appelle dans la commande find :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #!/bin/bash
     
    # récupération des arguments :
    # 1. fichier à déplacer
    # 2. dossier de destination
    cur_file=$1
    target_dir=$2
    # suppression du './' généré par find
    sub_path=${cur_file:2}
    # concaténation avec le répertoire cible
    target_file=$target_dir/$sub_path
    # move
    mv $cur_file $target_file
    Du coup la commande deviendrait : find . -iname "*Copie*" -exec /path/to/script.sh '{}' "~/backup/" \;.

    Ici le script tient compte du fait que la commande find est lancée en relatif à la racine du répertoire à "copier", si ce n'est pas le cas il faut lui apporter quelques modifs (et il serait beaucoup plus complexe).

    PS:
    A l'attention des experts qui lisent ce forum: je ne suis pas un guru linux. Si mon script n'est pas "joli", merci de le dire, de dire en quoi et surtout pourquoi au lieu de moinser.
    C'est le genre de script que je fais pour moi et qui marche, après il est certainement améliorable, il est sûrement truffé de failles de sécurités et il manque très probablement de contrôles.

  5. #5
    Membre du Club
    Inscrit en
    Mars 2008
    Messages
    80
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 80
    Points : 41
    Points
    41
    Par défaut
    Merci à tous les 3. Le problème est qu'il faudrait un mkdir pour recréer chacun des sous répertoire à déplacer de façon récursive non ? Il me semblait pourtant que mv, cp ou find avait un argument qui permettait de recréer le chemin tout en faisant un filtre ; j'ai même fait ça il y a quelques temps mais je ne parviens pas à me souvenir comment, et je ne vois pas quel serait l'argument dans les man...

  6. #6
    Expert confirmé
    Avatar de Loceka
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    2 276
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 2 276
    Points : 4 845
    Points
    4 845
    Par défaut
    Dans le script que j'ai donné, avant le mv tu peux faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    target_path=$(dirname $target_file)
    if [ "$target_path" != "." -a ! -e "$target_path" ]
    then
      mkdir -p "$target_path"
    fi
    qui crée l'arborescence si le répertoire n'existe pas et est différent de '.'.

  7. #7
    Membre habitué
    Homme Profil pro
    consultant ETL
    Inscrit en
    Septembre 2008
    Messages
    97
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : consultant ETL
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2008
    Messages : 97
    Points : 185
    Points
    185
    Par défaut find tar
    je proposerais bien une combinaison avec la commande find pour lister tes fichiers, pipé avec un tar pour tarer dans la sortie standard, pipé avec un tar pour detarer dans ton arborescence....

  8. #8
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    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 690
    Points : 30 986
    Points
    30 986
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par qqcvd Voir le message
    je proposerais bien une combinaison avec la commande find pour lister tes fichiers, pipé avec un tar pour tarer dans la sortie standard, pipé avec un tar pour detarer dans ton arborescence....
    Salut
    Tu y étais presque. Ta manip est très adapté quand on veut dupliquer une arborescence
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tar cf - dossier_depart | (cd dossier_arrivee; tar xpvf -)
    Ca recrée l'arborescence "dossier_depart" sous dossier_arrivee.

    Avantage, ce genre de commande traverse même le réseau
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tar zcf - dossier_depart | ssh host "cd dossier_arrivee; tar zxpvf -"
    Mais adapter cette astuce à un ensemble de fichiers issus de find (style tar cf - $(find ...) peut vite devenir lourd, voire planter si le find renvoie trop d'éléments t'obligeant à rajouter alors un xargs ce qui deviendra alors usine à gaz ; usine inutile vu qu'il y a un principe analogue mais beaucoup plus adapté basé sur cpio
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find -iname "*Copie*" |cpio -pvd ~/backup
    Et c'est torché
    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]

  9. #9
    Rédacteur/Modérateur
    Avatar de Winnt
    Homme Profil pro
    budget et contrôle de gestion
    Inscrit en
    Décembre 2006
    Messages
    1 978
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France

    Informations professionnelles :
    Activité : budget et contrôle de gestion
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 978
    Points : 4 130
    Points
    4 130
    Par défaut
    Salut,

    Et rsync il le fait pas tout ca des fois ?
    Winnt
    Merci de lire les règles du forum LaTeX et Qu'est ce qu'un ECM ?.
    N'hésitez pas à parcourir la FAQ la réponse y est peut-être déjà.
    Pensez au bouton si votre problème est résolu.


    C'est en Linuxant qu'on devient .... geek
    Et c'est en LateXant qu'on devient flemmard
    Mon blog tout neuf.
    Articles : présentation de la distribution Gentoo, Les index sous LaTeX et leur personnalisation.

  10. #10
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    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 690
    Points : 30 986
    Points
    30 986
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Winnt Voir le message
    Salut,

    Et rsync il le fait pas tout ca des fois ?
    Bah oui il le fait mais c'est un gros outil à mettre en place (configuration etc) pour un but si restreint atteint en une seule instruction.
    C'est un outil plus axé "sauvegardes périodiques" que "copie ponctuelle". Effectivement si la copie commence à devenir plus répétitive...
    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
    Invité
    Invité(e)
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    liste=`find -iname "*Copie*" -exec ls {}\;
    for fic in $liste;do cp -r $fic ~/backup/$fic;done
    Le liste contient les fichiers à copier avec le nom des répertoires.
    Le for les copie dans ~/backup/ en gardant le nom trouvé avant.
    Le -r du cp permet de créer les répertoires manquants.

    Pas sûr à 100% que ça fonctionne chez toi par contre.

  12. #12
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    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 690
    Points : 30 986
    Points
    30 986
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Beginner.j Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    liste=`find -iname "*Copie*" -exec ls {}\;
    for fic in $liste;do cp -r $fic ~/backup/$fic;done
    Pas sûr à 100% que ça fonctionne chez toi par
    contre.
    Surtout sûr à 100% que ça ne fonctionnera pas
    1) pour les fichiers dont le nom contient un espace
    2) pour les liens
    Pourquoi refaire en compliqué et de façon si bancale ce qui marche déjà en simple ???
    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]

  13. #13
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Surtout sûr à 100% que ça ne fonctionnera pas
    1) pour les fichiers dont le nom contient un espace
    2) pour les liens
    Pourquoi refaire en compliqué et de façon si bancale ce qui marche déjà en simple ???
    J'avais pensé aux espaces, mais avec des "" ça aurait pu résoudre ce problème... Ah ben non, ça résout le problème des espaces dans le cp mais pas dans la liste du find ><

    Par contre je n'avais pas pensé aux liens ...
    Dernière modification par Invité ; 07/12/2012 à 07h31.

  14. #14
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    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 690
    Points : 30 986
    Points
    30 986
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Beginner.j Voir le message
    J'avais pensé aux espaces, mais avec des "" ça aurait pu résoudre ce problème... Ah ben non, ça résout le problème des espaces dans le cp mais pas dans la liste du find ><
    Cause "for" qui se cale sur l'espace pour découper ses éléments.

    Solution (toujours bancale ici mais qui peut être utilisée dans un autre contexte)
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    find ... | while read f 
    do
        traitement "$f"
    done
    Mais qui ne sait pas non plus distinguer un lien d'un autre (ce qui n'est généralement pas très grave si on ne copie pas le fichier traité)...
    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]

  15. #15
    Membre habitué
    Homme Profil pro
    consultant ETL
    Inscrit en
    Septembre 2008
    Messages
    97
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : consultant ETL
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2008
    Messages : 97
    Points : 185
    Points
    185
    Par défaut arborescence
    Citation Envoyé par Sve@r Voir le message
    cpio
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find -iname "*Copie*" |cpio -pvd ~/backup
    cpio me fait penser a une combinaison de commandes qu'un admin m'avait passé mais je l'ai paumée : je cherchais à dupliquer toute une arborescence en conservant les droits des répertoires, mais sans les fichiers.
    Saurais tu comment faire ?

  16. #16
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    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 690
    Points : 30 986
    Points
    30 986
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par qqcvd Voir le message
    Citation Envoyé par Sve@r Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find -iname "*Copie*" |cpio -pvd ~/backup
    cpio me fait penser a une combinaison de commandes qu'un admin m'avait passé mais je l'ai paumée : je cherchais à dupliquer toute une arborescence en conservant les droits des répertoires, mais sans les fichiers.
    Saurais tu comment faire ?
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    find dossier_depart -type d |cpio -pvd dossier_destination
    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]

  17. #17
    Membre éclairé Avatar de jmelyn
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Septembre 2007
    Messages
    703
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Septembre 2007
    Messages : 703
    Points : 823
    Points
    823
    Par défaut
    Comme le préconise Winnt, le plus simple est d'utiliser la commande rsync. Et il n'y a aucune configuration à mettre en place, rsync peut fonctionner en client serveur, mais cette commande est aussi utilisée en local (sans serveur).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    rsync -a --remove-source-files --include='*Copie' --include='*/' --exclude='*' bureau/ backup/
    Bon, les règles ne sont pas évidentes au premier abord, mais en testant...

    Edit: avec rsync, il n'y a qu'une seule commande et les fichiers sont effacés du répertoire source.
    Un problème bien posé est déjà résolu (H. Bergson).

  18. #18
    Membre du Club
    Inscrit en
    Mars 2008
    Messages
    80
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 80
    Points : 41
    Points
    41
    Par défaut
    Excellent, rsync me va tout à fait, même si cpio marche très bien. Merci à tous !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 0
    Dernier message: 11/11/2010, 23h35
  2. Réponses: 1
    Dernier message: 19/05/2010, 10h30
  3. Copier des fichiers sur une clé USB, problème pour le chemin.
    Par monsieurY dans le forum Scripts/Batch
    Réponses: 21
    Dernier message: 21/01/2010, 09h56
  4. Réponses: 6
    Dernier message: 15/10/2009, 12h14
  5. Batch pour copier des fichier
    Par borgfabr dans le forum Scripts/Batch
    Réponses: 3
    Dernier message: 09/03/2004, 07h55

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