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

Administration système Discussion :

Copie de fichier d'après un historique annexe


Sujet :

Administration système

  1. #1
    Candidat au Club
    Inscrit en
    Juin 2010
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Juin 2010
    Messages : 10
    Points : 2
    Points
    2
    Par défaut Copie de fichier d'après un historique annexe
    Bonjour à tous

    Alors, je cherche à récupérer les fichiers images d'un dossier (qui est mise à jour automatiquement) par leur extension (ça pas de soucis) puis je cherche à les copier dans un dossier ou un script php d'un site s'occupe d'eux (renommage et création d'un fichier xml).
    Le souci c'est que vu que le script PHP les renomme, quand je relance ma copie il les remet et le script les renomme et ainsi de suite. J'ai donc tenté d'utiliser la commande --backup d'rsync avec un dossier --backup-dir définie, mais cela ne fonctionne toujours pas, il continue de renvoyer les fichier dans le dossier de backup malgré leurs présence dans le dossier 'incremental'. Pas mal de personne m'ont aidé avec Rsync mais je pense être bloqué et surtout je ne suis pas sur qu'Rsync soit la bonne solution.

    Voici mon code initial, mais bon il ne fonctionne pas comme je le veux et je pense qu'il faut partir sur quelque chose de différent: un script qui permet de copier des fichiers (ou pas) en fonction d'un historique annexe.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    #!/bin/bash
    find '/home/nom/image' -name '*.jpg' | while read FILE ; do rsync --backup --backup-dir=incremental --suffix=.old  "$FILE" /var/www/media ; done
    wget --spider 'http://monscript.php' ;
    #exit 0


    Merci d'avance pour votre aide.

    PS; un ptit plus serait de remplacer les points par un espace juste après avoir copié les *.jpeg. Mon script a du mal à différencier les deux. Je pensais refaire une commande find et chercher les fichiers puis leur faire sauter leurs point avec 'sed'?

  2. #2
    Membre actif

    Profil pro
    Inscrit en
    Août 2009
    Messages
    156
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 156
    Points : 211
    Points
    211
    Par défaut refonte complète du script
    Perso je referais l'ensemble dans un shell "basique" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    DEST_DIR=./destination
    HIST_DIR=./images_bck
    SOURCE_DIR=./images
    for file in $(find ${SOURCE_DIR}/ -name '*.jpg');do
      file_name=$(basename ${file})
      if [ ! -f ${HIST_DIR}/${file_name}.old ];then
        # Copie de sauvegarde (a remplacer par un touch ${HIST_DIR}/${file}.old si on veut juste une trace)
        cp -p ${file} ${HIST_DIR}/${file_name}.old
        # Deplacement vers le repertoire de destination
        mv ${file} ${DEST_DIR}
      fi
    done
    echo "Appel a wget"
    C'est plus long, mais plus simple, et plus flexible et évolutif que de continuer avec rsync.
    Pour ton problème de "." et de sed je n'ai pas bien saisi ce que tu veux faire.

  3. #3
    Candidat au Club
    Inscrit en
    Juin 2010
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Juin 2010
    Messages : 10
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par 50Nio Voir le message
    Perso je referais l'ensemble dans un shell "basique" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    DEST_DIR=./destination
    HIST_DIR=./images_bck
    SOURCE_DIR=./images
    for file in $(find ${SOURCE_DIR}/ -name '*.jpg');do
      file_name=$(basename ${file})
      if [ ! -f ${HIST_DIR}/${file_name}.old ];then
        # Copie de sauvegarde (a remplacer par un touch ${HIST_DIR}/${file}.old si on veut juste une trace)
        cp -p ${file} ${HIST_DIR}/${file_name}.old
        # Deplacement vers le repertoire de destination
        mv ${file} ${DEST_DIR}
      fi
    done
    echo "Appel a wget"
    C'est plus long, mais plus simple, et plus flexible et évolutif que de continuer avec rsync.
    Pour ton problème de "." et de sed je n'ai pas bien saisi ce que tu veux faire.
    Merci beaucoup je vais tester cela.

    Pour le "PS" en faite, mon script php considère que ce qui est après le point est l'extension, et quand il y a deux points dans le nom complet du fichier ça fonctionne pas très bien. Je me demandais si je pouvais pas rajouter une fonction pour remplacer le point par un espace. Par contre, il faudrait qu'elle agisse après la copie dans le dossier de destination?

  4. #4
    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 389
    Points
    19 389
    Par défaut
    Bonjour,

    un shell, même basique, ne fait pas for element in $(commande).

    Imagine que commande sorte des éléments contenant des espaces (ou pire, comme il est dit), alors la boucle for itérera sur chacune des composantes de chaque élément.
    Et là, patatra !
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  5. #5
    Candidat au Club
    Inscrit en
    Juin 2010
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Juin 2010
    Messages : 10
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    Bonjour,

    un shell, même basique, ne fait pas for element in $(commande).

    Imagine que commande sorte des éléments contenant des espaces (ou pire, comme il est dit), alors la boucle for itérera sur chacune des composantes de chaque élément.
    Et là, patatra !
    Aïe, que dois je faire du coup..? :/

  6. #6
    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 389
    Points
    19 389
    Par défaut
    Citation Envoyé par Benoitt
    Aïe, que dois je faire du coup..? :/
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find "$rep" [] -exec sh -c 'commandes_SH' {} {} \;
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  7. #7
    Candidat au Club
    Inscrit en
    Juin 2010
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Juin 2010
    Messages : 10
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find "$rep" [] -exec sh -c 'commandes_SH' {} {} \;
    Merci N_Bah mais j'ai du mal à faire le lien avec ce qu'il y a avant. Je suis désolé bien regarder, je ne trouve pas.

  8. #8
    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 389
    Points
    19 389
    Par défaut
    ce n'est pas le shell qui itère sur la sortie de find, c'est find qui itère les commandes shell pour chaque fichier.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  9. #9
    Candidat au Club
    Inscrit en
    Juin 2010
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Juin 2010
    Messages : 10
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    ce n'est pas le shell qui itère sur la sortie de find, c'est find qui itère les commandes shell pour chaque fichier.
    Je ne comprends pas où tu veux en venir. Désolé.

  10. #10
    Membre actif

    Profil pro
    Inscrit en
    Août 2009
    Messages
    156
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 156
    Points : 211
    Points
    211
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    un shell, même basique, ne fait pas for element in $(commande).
    Ben, si, le ksh gère ça en natif directement, Unix/Linux etc... ?!? $(commande) est exécuté, tu récupère une liste de chaines de caractères, et le for boucle dessus.

    Sinon, le problème des espaces est vrai. Si tes fichiers contiennent des espaces, le for va séparer sur les espaces, donc un fichier "image meteo.jpg" va déclencher deux fois la boucle, une sur "image" et une sur "meteo.jpg". Pour gérer ce cas là, il faut à nouveau tout revoir, soit avec find, soit avec un while.

    Pour le find, l'option "-exec" permet d'exécuter une commande sur chaque résultat que le find a trouvé. Dans cette syntaxe "{}" représente ton résultat, et "\;" la fin de la commande shell à exécuter.
    Faut que j'essaye, j'ai jamais utilisé find sur des commandes plus complexe qu'un rm par exemple.

  11. #11
    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 389
    Points
    19 389
    Par défaut
    oui, je me suis mal exprimé :
    en shell, même basique, on ne fait pas (on ne doit pas faire) for element in $(commande).
    à force de me répéter, j'essaye de varier un peu, mais là ça n'a pas fonctionné
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  12. #12
    Membre actif

    Profil pro
    Inscrit en
    Août 2009
    Messages
    156
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 156
    Points : 211
    Points
    211
    Par défaut
    Dans ce cas je suis d'accord, la méthode for i in $(commande) est en effet trop simple pour gérer les espaces dans les résultats !

    Je n'arrive pas à faire une version avec find qui lancerait une fonction ou plusieurs commandes.

    Une version avec while, qui gère les espaces dans les noms de fichier :
    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
    #!/bin/ksh
    DEST_DIR=./destination
    HIST_DIR=./images_bck
    SOURCE_DIR=./images
     
    find ${SOURCE_DIR} -name "*.jpg" >${HIST_DIR}/tmp.file
    exec 3<${HIST_DIR}/tmp.file
     
    while read file <&3;do
      file_name=$(basename "${file}")
      if [ ! -f "${HIST_DIR}/${file_name}.old" ];then
        cp -p "${file}" "${HIST_DIR}/${file_name}.old"
        mv "${file}" "${DEST_DIR}"
      fi
    done
    exec 3<&-
    [ -f ${HIST_DIR}/tmp.file ] && rm -f ${HIST_DIR}/tmp.file
    while read valeur <fichier utilise la fin de ligne comme séparateur, pas "tous les blancs", donc va gérer les noms de fichier avec des espaces (et aussi avec des tabulations, mais là franchement ... ptêt le nom du fichier serait abusé).
    Autour des commandes mv ou cp, il faut aussi du coup encapsuler tes arguments dans des guillemets pour que le shell interprète "image avec un blanc.jpg" comme un seul argument et non comme 4 arguments distincts.
    exec permet d'ouvrir et de fermer proprement des filedescripteurs.

  13. #13
    Candidat au Club
    Inscrit en
    Juin 2010
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Juin 2010
    Messages : 10
    Points : 2
    Points
    2
    Par défaut
    Merci bien. J'y vois petit à petit de plus en plus clair.

    J'essaye tout cela.

  14. #14
    Candidat au Club
    Inscrit en
    Juin 2010
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Juin 2010
    Messages : 10
    Points : 2
    Points
    2
    Par défaut
    Malheureusement je rencontre un message d'erreur à propos du tmp.file

    Même si je créé un fichier ou un dossier nommé tmp.file cela ne fonctionne pas...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    benoit@debian:~$ '/home/benoit/Desktop/script4.ksh' 
    /home/benoit/Desktop/script4.ksh[6]: ./media/NewVolume/History/tmp.file: cannot create [No such file or directory]
    /home/benoit/Desktop/script4.ksh[7]: ./media/NewVolume/History/tmp.file: cannot open [No such file or directory]
    Les lignes 6 et 7 étant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    find ${SOURCE_DIR} -name "*.jpeg" >${HIST_DIR}/tmp.file
    exec 3<${HIST_DIR}/tmp.file

  15. #15
    Membre actif

    Profil pro
    Inscrit en
    Août 2009
    Messages
    156
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Août 2009
    Messages : 156
    Points : 211
    Points
    211
    Par défaut
    Vérifie que HIST_DIR pointe sur /media/NewVolume/History/ et non pas ./media/NewVolume/History/ ou media/NewVolume/History/

    Ton répertoire doit être mal paramétré.

  16. #16
    Candidat au Club
    Inscrit en
    Juin 2010
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Juin 2010
    Messages : 10
    Points : 2
    Points
    2
    Par défaut
    Merci beaucoup le script fonctionne pour le moment, malgré le fait que les fichiers du dossier média disparaissent.

    J'ai donc fait une modif ligne 13.

    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
    #!/bin/ksh
    DEST_DIR=/destination
    HIST_DIR=/images_bck
    SOURCE_DIR=/images
     
    find ${SOURCE_DIR} -name "*.jpg" >${HIST_DIR}/tmp.file
    exec 3<${HIST_DIR}/tmp.file
     
    while read file <&3;do
      file_name=$(basename "${file}")
      if [ ! -f "${HIST_DIR}/${file_name}.old" ];then
        cp -p "${file}" "${HIST_DIR}/${file_name}.old"
        cp "${file}" "${DEST_DIR}"
      fi
    done
    exec 3<&-
    [ -f ${HIST_DIR}/tmp.file ] && rm -f ${HIST_DIR}/tmp.file
    J'ai tenté également d'ajouter une ligne à la fin pour remplacer les points par des underscores.

    En utilisant ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    benoit@debian:/var/www/media$ find -name '*.jpg' -execdir rename 's/./_/' {} +
    Can't rename ./02. mairie.jpg _/02. mairie.jpg: No such file or directory
    Il semblerait que j'ai encore un problème de chemin, je ne comprends pas trop.

    Merci encore

    Je peux difficilement masquer ma joie.

  17. #17
    Candidat au Club
    Inscrit en
    Juin 2010
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Juin 2010
    Messages : 10
    Points : 2
    Points
    2
    Par défaut
    Hello

    Bon je suis partie d'un script un peu "assisté" pour arriver à mes fins.

    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
    21
    22
    23
    24
    25
    26
    27
    28
    #!/bin/bash
    if [ $# -lt 1 ] || [ "$1" == "-h" ] || [ "$1" == "--help" ]; then
        echo "" >&2
        echo "Usage: $0 [ -h | --help ]" >&2
        echo "       $0 file .." >&2
        echo "" >&2
        echo "This will transform the name of the specified file(s)." >&2
        echo "" >&2
        exit 0
    fi
     
    for path in "$@" ; do
        dir="`dirname "$path"`"
        file="`basename "$path"`"
     
        # Split file name and extension
        ext=".${file##*.}"
        old="${file%.*}"
        [ "$old" == "$file" ] && ext=""
        new="$old"
     
        # Modify "$new" to suit your needs. Dots to spaces:
        new="${new//./ }"
     
        if [ "$new" != "$old" ]; then
            mv -vi "$dir/$old$ext" "$dir/$new$ext" || exit $?
        fi
    done
    Trouvé ici https://www.linuxquestions.org/quest...ension-871417/

    Puis je utiliser le path de la ligne 12 avec le $DEST_DIR que j'utilise précédement dans mon script et lui spécifier de suite l'extension. J'ai du mal à trouver.

    Pour j'appelle l'ouvre mon dossier puis appel mon script suivis de l’extension *.jpeg

    Dernière question, puis-je intégrer ce code en brut dans un script en ksh.

Discussions similaires

  1. fichier illisible après copie
    Par Bernabé01 dans le forum Débuter
    Réponses: 13
    Dernier message: 29/01/2013, 21h55
  2. Réponses: 2
    Dernier message: 01/02/2012, 10h43
  3. Copie de fichier sans perte d'historique
    Par genzo93 dans le forum Développement Sharepoint
    Réponses: 0
    Dernier message: 29/04/2010, 15h55
  4. Copie de fichiers après génération
    Par bouba dans le forum Visual Studio
    Réponses: 0
    Dernier message: 28/04/2010, 18h06
  5. Fichier corrompu après copie
    Par Patricia_ dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 11/08/2009, 11h16

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