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 POSIX Discussion :

Script Shell - récursivité


Sujet :

Shell et commandes POSIX

  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2014
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Mayenne (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2014
    Messages : 20
    Par défaut Script Shell - récursivité
    Bonjour à tous et merci par avance de votre aide.
    Je suis novice en scripting Shell et je bloque actuellement sur une fonction permettant une lecture récursive des répertoires.

    J'ai essayé avec la commande ls -R -l (car j'ai besoin de la date de modification) sauf que les résultats ne s'affichent pas comme je le souhaite. Exemple :

    3 dossiers XXX, 3 sous dossiers dans chaque dossier XXX que l'on va nommé YYY et enfin mes fichiers ZZZ contenu dans mes sous dossiers YYY.
    Les résultats s'affichent de cette façon

    Dossier 1 XXX
    Dossier 2 XXX
    Dossier 3 XXX

    Sous-dossier 1 YYY
    Sous-dossier 1 YYY
    Sous-dossier 1 YYY

    Sous-dossier 2 YYY
    Sous-dossier 2 YYY
    Sous-dossier 2 YYY

    Sous-dossier 3 YYY
    Sous-dossier 3 YYY
    Sous-dossier 3 YYY

    Fichier ZZZ (Correspondant au sous dossier 1)
    Fichier ZZZ (Correspondant au sous dossier 1)
    Fichier ZZZ (Correspondant au sous dossier 2)
    Fichier ZZZ (Correspondant au sous dossier 2)
    Fichier ZZZ (Correspondant au sous dossier 3)
    Fichier ZZZ (Correspondant au sous dossier 3)
    (* le nombre de sous dossiers.)

    Alors que je souhaiterai un tri comme ceci :

    Dossier 1 XXX
    Sous-dossier 1 YYY
    Fichier 1 ZZZ
    Fichier 2 ZZZ
    Sous-dossier 2 YYY
    Fichier 1 ZZZ
    Fichier 2 ZZZ

    Dossier 2 XXX
    Sous-dossier 1 YYY
    Fichier 1 ZZZ
    Fichier 2 ZZZ
    Sous-dossier 2 YYY
    Fichier 1 ZZZ
    Fichier 2 ZZZ

    J'ai vu des méthodes en écrivant tous les paths des dossiers et en bouclant dessus mais j'en ai un nombre important (environ 160 contenant tous une dizaine de sous dossiers) j'imagine donc qu'il y a probablement une autre solution...

    Merci,
    Leam

  2. #2
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    1 946
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 946
    Par défaut
    Salut,

    Regarde du côté de la commande tree

  3. #3
    Expert confirmé Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 293
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 293
    Par défaut
    Bonjour,

    Citation Envoyé par un illustre inconnu
    On utilise pas ls dans un script!
    Plutôt que d'utiliser "ls" pour trouver les fichiers, pourquoi ne pas utiliser "find" ?

    Plutôt que d'utiliser "ls" pour avoir la date de modification, pourquoi ne pas utiliser "stat" comme les commandes suivantes ?

  4. #4
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2014
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Mayenne (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2014
    Messages : 20
    Par défaut
    J'ai essayé de faire un man tree dans mon terminal et la commande n'est pas trouvée.
    J'ai oublié de préciser que je suis sous Mac OS(10.6.8).. Cela doit avoir une incidence.

    Pourquoi ne faut-il pas utiliser le "ls" dans un script ?
    J'essaye avec la commande Find et stat, je vous tiens au courant de l'avancée.

  5. #5
    Membre Expert
    Avatar de Escapetiger
    Homme Profil pro
    Administrateur système Unix - Linux
    Inscrit en
    Juillet 2012
    Messages
    1 562
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Administrateur système Unix - Linux

    Informations forums :
    Inscription : Juillet 2012
    Messages : 1 562
    Par défaut
    Citation Envoyé par LeamCart Voir le message
    Pourquoi ne faut-il pas utiliser le "ls" dans un script ?
    Nos modérateurs préférés de la rubrique nous le rapellent à juste titre régulièrement, voir la FAQ Linux ci-dessous :
    Pourquoi faut-il eviter la commande ls dans les scripts ?
    « Developpez.com est un groupe international de bénévoles dont la motivation est l'entraide au sens large » (incl. forums developpez.net)
    Club des professionnels en informatique

    Liste des balises BB

  6. #6
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2014
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Mayenne (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2014
    Messages : 20
    Par défaut
    Merci, je prend en compte cette information.
    Néanmoins je n'ai pas vraiment eu réponse à ma question (mis à part la fonction tree qui n'existe pas chez moi).
    Il n'existe aucune autre façon que de boucler indéfiniment sur mes 1600 dossiers et de récupérer les informations que je souhaite en les triant "un à un"?

  7. #7
    Expert confirmé Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 293
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 293
    Par défaut
    Pardon, mais ça ressemble à une fausse bonne idée. C'est peut-être à-peu-près lisible pour un humain, mais pour tout autre traitement industriel, éclater le chemin ainsi est mauvais.

    Avec le find tu as toutes les infos dont tu as besoin. Après c'est juste de la manipulation de fichiers texte avec sed, grep, awk.

    Quelle est la finalité ?

  8. #8
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2014
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Mayenne (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2014
    Messages : 20
    Par défaut
    La finalité est de pouvoir copier les informations sur un fichier texte comme ceci :

    Phototheque

    NomRepertoire1(1er)
    NomRepertoire1 (2 iem)
    dateModif nomFichier
    dateModif nomFichier
    dateModif nomFichier

    NomRepertoire2 (1er)
    NomRepertoire2 (2 iem)
    dateModif nomFichier
    dateModif nomFichier
    dateModif nomFichier

    dateModif étant la date de modification du fichier.

  9. #9
    Expert confirmé Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 293
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 293
    Par défaut
    Un exemple (à toi d'adapter):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     find . -type f | sort | while read fichier; do echo "$fichier"";"$(stat -c "%y" "$fichier");done |sed 's@.*/@&;@;'|awk -F';' '($1!=dossier){dossier=$1;print "\n"$1"\n"$1;} {print $2,$3;}'
    et la sortie:
    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
    35
    ./wp-content/themes/bonpress-via-wp-themes-pro/bonpress/scripts/
    ./wp-content/themes/bonpress-via-wp-themes-pro/bonpress/scripts/
    timthumb.php 2011-08-20 22:49:20.000000000 +0200
     
    ./wp-content/themes/bonpress-via-wp-themes-pro/bonpress/
    ./wp-content/themes/bonpress-via-wp-themes-pro/bonpress/
    search.php 2011-08-19 16:33:48.000000000 +0200
    searchform.php 2011-08-19 16:14:16.000000000 +0200
    sidebar.php 2011-08-19 16:17:46.000000000 +0200
    single.php 2011-08-19 16:26:10.000000000 +0200
    style.css 2011-08-19 16:14:14.000000000 +0200
     
    ./wp-content/themes/bonpress-via-wp-themes-pro/bonpress/styles/
    ./wp-content/themes/bonpress-via-wp-themes-pro/bonpress/styles/
    black.css 2011-08-19 16:06:28.000000000 +0200
    blue.css 2011-08-19 16:06:26.000000000 +0200
    orange.css 2011-07-08 22:15:44.000000000 +0200
    pink.css 2011-08-19 16:08:00.000000000 +0200
     
    ./wp-content/themes/bonpress-via-wp-themes-pro/bonpress/
    ./wp-content/themes/bonpress-via-wp-themes-pro/bonpress/
    template-archive.php 2011-08-19 16:02:06.000000000 +0200
     
    ./wp-content/themes/bonpress-via-wp-themes-pro/bonpress/wpzoom_admin/
    ./wp-content/themes/bonpress-via-wp-themes-pro/bonpress/wpzoom_admin/
    admin_functions.php 2011-08-19 16:05:46.000000000 +0200
     
    ./wp-content/themes/bonpress-via-wp-themes-pro/bonpress/wpzoom_admin/images/
    ./wp-content/themes/bonpress-via-wp-themes-pro/bonpress/wpzoom_admin/images/
    back_nav_active.png 2011-08-19 16:28:42.000000000 +0200
    back_nav_inactive.png 2011-08-19 16:02:56.000000000 +0200
    back_top.png 2011-08-19 16:04:24.000000000 +0200
    icon_adobe.png 2011-08-19 16:30:22.000000000 +0200
    icon_banner.png 2011-08-19 16:23:46.000000000 +0200
    icon_home.png 2011-08-19 16:31:22.000000000 +0200

  10. #10
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2014
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Mayenne (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2014
    Messages : 20
    Par défaut
    J'ai le résultat que je souhaitait, merci pour cette aide.
    Excellente journée à vous, sujet résolu !

  11. #11
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2014
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Mayenne (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2014
    Messages : 20
    Par défaut
    Re-bonjour à tous, je poste à la suite afin d'éviter d'en ouvrir un autre.

    J'ai un petit problème sur une boucle imbriquée. Voici mon code :

    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
     
    while IFS=$' ' read nomAsset2 dateModif2 
    do
    	while IFS=$' ' read nomAsset1 dateModif1 
    	do
                    echo "$nomAsset2 - $nomAsset1"
    		if [ "$nomAsset2" == "$nomAsset1" ]
    		then
    			Ajout="0"
    			break
    			if [ "$dateModif2" == "$dateModif1" ]
    			then
    				Modif="0"
       				break	
    			fi
    		fi
    	done < /Users/Desktop/fichier1.txt
     
    	if [ "$Ajout" == "1" ]
    	then
    			echo "---> Ajout $nomAsset2" >> /Users/Desktop/LOGFILE.txt
    	elif [ "$Modif" == "1" ]
    	then
    			echo "---> Modif $nomAsset2" >> /Users/Desktop/LOGFILE.txt
    	fi
    done < /Users/Desktop/fichier2.txt
    Dans le cas présent nous passons correctement dans la première boucle afin de trouver "nomAsset2", nous passons ensuite dans la deuxième boucle while et nous trouvons "nomAsset1". Logiquement (d'après ma logique) grâce à la deuxième boucle while je peux tester mon nomAsset2 sur toutes les possibilités de nomAsset1; SAUF que il ne boucle pas sur toutes les lignes du fichier 1 et repasse à l'autre boucle à chaque fin de tour...
    (Exemple si vous ne m'avez pas trop compris..)

    Fichier 2
    image5353
    image5656
    image7575
    image9696

    fichier 1
    image5656
    image7575
    image9696
    image5353

    Mon code va faire (je reprend la valeur de mon echo ligne 6 :
    image5353 - image5656
    image5656 - image7575
    image7575 - image9696
    image9696 - image5353

    Alors que dans la logique :
    image5353 - image5656
    image5353 - image7575
    image5353 - image9696
    image5353 - image5353

    et puisqu'il rentre dans ma condition comme quoi il est égale je break et ça peut enfin changer de nomAsset2.

    Je ne comprend pas mon erreur..
    Merci de nouveau par avance de votre aide.

    Leam

  12. #12
    Expert confirmé Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 293
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 293
    Par défaut
    1. Tu es toujours dans la manipulation de fichiers texte. Ce n'était donc pas la finalité.
    2. Bizarres ces breaks. Je me demande le but.
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      $ help break
      break: break [n]
          Exit for, while, or until loops.
       
          Exit a FOR, WHILE or UNTIL loop.  If N is specified, break N enclosing
          loops.
       
          Exit Status:
          The exit status is 0 unless N is not greater than or equal to 1.

  13. #13
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2014
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Mayenne (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2014
    Messages : 20
    Par défaut
    C'était la finalité pour la première étape. La deuxième ne devait pas poser tant de problèmes.
    Si j'ai bien compris le break permet de quitter la boucle actuelle, et donc ça correspond à ce que j'ai voulu faire. En effet, lorsque mon nomAsset2 rencontre sa concordance avec nomAsset1 alors je break afin qu'il évite d'aller plus loin dans le fichier puisqu'il boucle sur toutes les lignes de mon fichier(et donc gagner un petit peu de temps).

    Par doute j'ai essayer de faire fonctionner mon code sans les breaks et j'ai le même problème au niveau de mes while.

    Ma question est maintenant : Pourquoi à chaque ligne il quitte la boucle ?

  14. #14
    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 LeamCart Voir le message
    C'était la finalité pour la première étape. La deuxième ne devait pas poser tant de problèmes.
    Si j'ai bien compris le break permet de quitter la boucle actuelle, et donc ça correspond à ce que j'ai voulu faire.
    ?!?!?!?

    Désolé, mais je doute vraiment que ça corresponde à ce que tu veux faire!!!

    Je n'ai pas vraiment lu ni compris ce code:

    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
     
    while IFS=$' ' read nomAsset2 dateModif2 
    do
    	while IFS=$' ' read nomAsset1 dateModif1 
    	do
                    echo "$nomAsset2 - $nomAsset1"
    		if [ "$nomAsset2" == "$nomAsset1" ]
    		then
    			Ajout="0"
    			break
    			if [ "$dateModif2" == "$dateModif1" ]
    			then
    				Modif="0"
       				break	
    			fi
    		fi
    	done < /Users/Desktop/fichier1.txt
     
    	if [ "$Ajout" == "1" ]
    	then
    			echo "---> Ajout $nomAsset2" >> /Users/Desktop/LOGFILE.txt
    	elif [ "$Modif" == "1" ]
    	then
    			echo "---> Modif $nomAsset2" >> /Users/Desktop/LOGFILE.txt
    	fi
    done < /Users/Desktop/fichier2.txt
    Je constate simplement que la ligne 10 contient l'instruction break.
    Lorsque le shell exécute cette ligne, il sort immédiatement de la boucle (la plus imbriquée).
    Cela veut dire que la ligne suivante (la ligne 11) ne sera jamais exécutée.

    Si c'est vraiment ce que tu veux faire, autant supprimer du code les lignes 11 à 15!

    Si tu veux comprendre ce qui se passe pas à pas, tu peux ajouter set -x en première ligne du script.

    De plus, pourquoi utiliser == dans les comparaisons plutôt que = ou -eq ?

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

Discussions similaires

  1. Script shell
    Par anzar dans le forum Linux
    Réponses: 4
    Dernier message: 03/12/2004, 14h41
  2. [JSP] script shell
    Par goolix dans le forum Servlets/JSP
    Réponses: 3
    Dernier message: 06/08/2004, 09h08
  3. Exécution d'un script shell
    Par Manu0086 dans le forum Linux
    Réponses: 8
    Dernier message: 15/06/2004, 16h31
  4. Explication script shell
    Par crasho007 dans le forum Linux
    Réponses: 2
    Dernier message: 14/06/2004, 13h54
  5. Cron + terminal + script shell
    Par nicolas.pissard dans le forum Linux
    Réponses: 3
    Dernier message: 17/03/2004, 09h24

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