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 :

Comment copier les fichiers d'un répertoire dans de nouveaux fichiers avec lenom+n ?


Sujet :

Shell et commandes GNU

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    508
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Haute Vienne (Limousin)

    Informations forums :
    Inscription : Avril 2008
    Messages : 508
    Par défaut Comment copier les fichiers d'un répertoire dans de nouveaux fichiers avec lenom+n ?
    Bonjour,

    je souhaiterai créer un script qui effectue une sorte de sauvegarde de chaque fichier présent dans le répertoire en le copiant dans un nouveau fichier dont le rang est nom_courant.n.
    Par exemple, si j'ai les fichiers toto et tata, après éxecution du script et un "ls" j'aurai les fichiers: toto tata toto.1 tata.1

    Je suis débutant dans la réalisation de script shell, si quelqu'un pouvait me donner un coup de main ???

    Merci d'avance, à bientôt !

  2. #2
    Membre émérite 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 : 61
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2007
    Messages : 703
    Par défaut
    Bonsoir,

    J'ai écrit le cas général, en Bash:

    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
    29
    30
    31
    32
    33
    34
    #!/bin/bash
    
    # vérifie le paramètre
    if [[ $# != 1 ]] || [[ ! -d $1 ]]
    then
      echo "Usage: $(basename $0) <répertoire>"
      exit 1
    fi
    
    # va dans le répertoire demandé
    cd $1
    
    # pour chaque fichier du répertoire (ordre alphabétique inverse)
    for fichier in $(ls -r)
    do
      # si c'est un fichier
      if [[ -f $fichier ]]
      then
        # extrait l'extension du nom du fichier
        extension=$(echo $fichier | awk -F '.' 'NF > 1 {print $NF}')
    
        # si l'extension existe et est numérique
        if [[ $extension =~ ^[0-9][0-9]*$ ]]
        then
          # copie le fichier avec une extension incrémentée
          cp -pf $fichier ${fichier%.*}.$((extension + 1))
     
        # sinon l'extension n'existe pas ou n'est pas numérique
        else
          # copie le fichier avec la première extension: ".1"
          cp -pf $fichier $fichier.1
        fi
      fi
    done

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    508
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Haute Vienne (Limousin)

    Informations forums :
    Inscription : Avril 2008
    Messages : 508
    Par défaut
    Bonjour,

    merci jmelyn pour ton aide !

    Alors j'ai essayé d'utiliser ton script mais j'ai les erreurs suivantes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    debian:/home/clem/Projet# ./creer_nouvelle_version
    ./creer_nouvelle_version: line 4: conditional binary operator expected
    ./creer_nouvelle_version: line 4: syntax error near `!=1'
    ./creer_nouvelle_version: line 4: `if [[ $# !=1 ]] || [[ ! -d $1 ]]'
    debian:/home/clem/Projet#
    Je ne comprend pas comment les résoudre !!!

  4. #4
    Membre émérite 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 : 61
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2007
    Messages : 703
    Par défaut
    Bonjour,

    Tu dois pouvoir le résoudre simplement en ajoutant un espace entre le '!=' et '1'. En effet, les espaces que l'on observe dans les scripts sont souvent obligatoires, et c'est un piège dans lequel les nouveaux programmeurs tombent souvent.

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    508
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Haute Vienne (Limousin)

    Informations forums :
    Inscription : Avril 2008
    Messages : 508
    Par défaut
    ok, c'était bien ça, merci jmelyn !!!

    C'est vrai que je m'acharnais à résoudre cette erreur et en fait c'est souvent plus simple que ce que l'on pense.

    Par contre, j'avais quelques questions :

    - j'essaie de modifier le script afin que cela ne me demande pas le répertoire mais qu'il séxecute dans le répertoire courant. Après modifications, quand je l'éxecute j'ai aucune erreur mais sans résultat !!!
    Est ce plus compliqué de faire ce que je souhaiterai ?

    - comment faire fonctionner un script dans n'importe quel répertoire, juste en tapant (dans mon cas par ex) : creer_nouvelle_version

    - qu'est ce qu'un programme qui fonctionne de manière récursive ?

    Merci, à bientôt !

  6. #6
    Membre expérimenté
    Profil pro
    Architecte de système d'information
    Inscrit en
    Mai 2007
    Messages
    248
    Détails du profil
    Informations personnelles :
    Âge : 72
    Localisation : France

    Informations professionnelles :
    Activité : Architecte de système d'information
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2007
    Messages : 248
    Par défaut
    Pour le faire fonctionner dans le répertoire courant

    modifier:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    # vérifie le paramètre
    if [[ $# != 1 ]] || [[ ! -d $1 ]]
    then
      echo "Usage: $(basename $0) <répertoire>"
      exit 1
    fi
     
    # va dans le répertoire demandé
    cd $1
    en...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    if [[ $# != 0 ]] 
    then
      echo "Usage: $(basename $0)"
      exit 1
    fi
    Un programme ou une fonction recursif(ve) est un programme/fonction qui se rappelle lui(elle) même tant qu'une condition n'est pas remplie.

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    508
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Haute Vienne (Limousin)

    Informations forums :
    Inscription : Avril 2008
    Messages : 508
    Par défaut
    OK, merci noooop, j'en étais pas loin !

    Par contre, peux tu me réexpliquer ou me donner un exemple sur les programmes fonctionnant de manière récursifs car je suis désolé mais je n'ai pas compris !!!

    Et comment faire fonctionner un script dans n'importe quel répertoire, juste en tapant (dans mon cas par ex) : creer_nouvelle_version

  8. #8
    Membre expérimenté
    Profil pro
    Architecte de système d'information
    Inscrit en
    Mai 2007
    Messages
    248
    Détails du profil
    Informations personnelles :
    Âge : 72
    Localisation : France

    Informations professionnelles :
    Activité : Architecte de système d'information
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2007
    Messages : 248
    Par défaut
    Récursivité: http://recursivite.developpez.com/?page=sommaire

    Si tu veux créer un script qui fonctionne dans le répertoire courant en ne tapant que le nom de ta commande, il faut que ta commande soit trouvée dans le PATH de ta session.

  9. #9
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    508
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Haute Vienne (Limousin)

    Informations forums :
    Inscription : Avril 2008
    Messages : 508
    Par défaut
    Merci noooop !

    Alors si j'ai bien compris un programme fonctionnant de manière récursif est un programme qui s'appelle lui même donc dans mon cas : mon programme s'exécuterai à chaque fois qu'il y aurait une nouvelle modification d'un fichier, non ?

    Et qu'est ce que le PATH de ma session ? Où puis je le trouver ?

  10. #10
    Membre expérimenté
    Profil pro
    Architecte de système d'information
    Inscrit en
    Mai 2007
    Messages
    248
    Détails du profil
    Informations personnelles :
    Âge : 72
    Localisation : France

    Informations professionnelles :
    Activité : Architecte de système d'information
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2007
    Messages : 248
    Par défaut
    Non, car si a chaque fois que ton programme se rappelle, qu'elle est ta condition de fin de récursivité ? A priori il n'y en a pas ! Donc tu va exploser la stack (à moins qu'un spécialiste du shell passe par ici et infirme ce que je te dis).

    La récursivité n'est pas une fin en soit. C'est une facilité d'écriture. La preuve c'est qu'il y a une litterature sur comment dérécursiver un programme récursif.

    Si tu veux rappeler ton programme dès qu'un fichier apparait fait une boucle infinie.

    Pour modifier TON path regarde le fichier $HOME/.bash_profile

    Par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    PATH=$PATH:/home/moi/scripts
    export PATH

  11. #11
    Membre émérite 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 : 61
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2007
    Messages : 703
    Par défaut
    Pour la récursivité, un programme peut s'appeler lui-même puisqu'il contient la condition de fin d'appel. Néanmoins cela ne se trouve que rarement parce qu'il manque l'initialisation du programme qui ne doit être exécutée qu'une seule fois. C'est pourquoi il n'y a, en général, qu'une partie du programme qui est récursive. C'est souvent une simple fonction.

    On a donc: Démarrage programme --> initialisation --> appel de la fonction récursive avec les paramètres idoines --> ré-appel de la fonction avec de nouveaux paramètres --> ... --> retour du dernier appel --> ... --> retour du premier appel --> fin de programme avec affichage des résultats.

  12. #12
    Membre émérite 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 : 61
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2007
    Messages : 703
    Par défaut
    Bonjour,

    Pour exécuter la sauvegarde des fichiers de manière récursive (dans les sous-répertoires du répertoire courant), il n'y a pas grand-chose à modifier: c'est une tâche administrative courante. Voici le code, modifié pour ne plus passer le répertoire en paramètre.
    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
    #!/bin/bash
    
    # pour chaque fichier du répertoire courant et des sous-répertoires
    #  (ordre numérique inverse)
    for fichier in $(find . -type f | sort -n -r)
    do
      # si c'est un fichier
      if [[ -f $fichier ]]
      then
        # extrait l'extension du nom du fichier
        extension=$(echo $fichier | awk -F '.' 'NF > 1 {print $NF}')
    
        # si l'extension existe et est numérique
        if [[ $extension =~ ^[0-9][0-9]*$ ]]
        then
          # copie le fichier avec une extension incrémentée
          cp -pf $fichier ${fichier%.*}.$((extension + 1))
     
        # sinon l'extension n'existe pas ou n'est pas numérique
        else
          # copie le fichier avec la première extension: ".1"
          cp -pf $fichier $fichier.1
        fi
      fi
    done
    Modification (en rouge):
    C'est la commande find qui récupère la liste de tous les fichiers (et uniquement les fichiers) du répertoire courant et de ses sous-répertoires. Il faut la trier à l'envers avec la commande sort -n -r afin de commencer à copier fichier.1 en fichier.2 puis fichier en fichier.1 parce que sinon on copie d'abord fichier en fichier.1 puis fichier.1 en fichier.2, et on a la même version dans fichier, fichier.1 et fichier.2! Et l'option -n de sort permet d'avoir l'ordre numérique 1 2 3 ... 8 9 10 11. En tri alphabétique on aurait: 1 10 11 2 3 4 ... 8 9. Le premier script que j'ai donné (utilisant la commande ls -r) ne doit sans doute pas fonctionner au-delà de l'indice 9.

    Pour appeler le script, il faut donner son chemin à partir du répertoire courant. Deux possibilités:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ../mes_scripts/sauvegarde_recursive
    /home/jmelyn/mes_scripts/sauvegarde_recursive
    Le premier appel est relatif, c'est-à-dire que le chemin est donné à partir du répertoire courant. Le second appel est absolu: le chemin est donné depuis la racine /.

Discussions similaires

  1. Lister les fichiers d'un répertoire dans une feuille Excel
    Par AlainTech dans le forum Contribuez
    Réponses: 7
    Dernier message: 15/02/2025, 17h06
  2. [MySQL] Comment regrouper les requetes d'un site dans un seul fichier php?
    Par planeurbret dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 26/01/2012, 16h39
  3. comment copier les items d'un menu dans un autre ?
    Par thierrybo dans le forum Débuter
    Réponses: 2
    Dernier message: 17/09/2010, 17h01
  4. Comment copier LES fichiers cachés d'un répertoire donné :-)
    Par gifffftane dans le forum Shell et commandes GNU
    Réponses: 6
    Dernier message: 25/06/2007, 17h57
  5. Réponses: 6
    Dernier message: 03/05/2006, 11h01

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