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 :

Fonction de scrutation de répertoire


Sujet :

Shell et commandes GNU

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Inscrit en
    Janvier 2014
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 2
    Points : 1
    Points
    1
    Par défaut Fonction de scrutation de répertoire
    Bonjour,

    J'essaye de passer un script de Solaris à Linux, le script fonctionne très ben sous Solaris.
    C'est une "simple" fonction qui parcours un répertoire et renvoi un nom de fichier.

    En pratique :
    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
    #_________________________ FONCTION DE SCRUTATION DE REPERTOIRE ________________
    #
    # Param 1 : nom du repertoire a scruter
    # Param 2 : nom du dernier fichier traite
    # Param 3 : type de recherche f pour fichier ou d pour repertoire
    #
    # Retour de la fonction :
    # La variable "Retour_Scrut" contient le nom du fichier suivant
    #
     
    Scrut_Rep() {
    if [ ! -d "$1" ]; then
       Retour_Scrut=""; return
    fi
     
    # on remplace dans le path de scrutation '/' par '\/'
    Sub_scrut=`echo $1 | sed -e "s/\/$//" -e "s/$/\//" | sed -e "s/\//\\\\\\\\\//g"`
     
    Retour_Scrut=`find $1 -type $3 | sed -e "s/$Sub_scrut//" | awk '{
     
       if (PREC != "" ) {
          while ( $0!=PREC && getline == 1 ) ;
          getline
       }
     
       while ( index($0,"/")!=0) getline
       print $0
       exit  }  ' PREC="$2"`
    }
    Typiquement on appelle cette fonction dans une boucle du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Scrut_Rep $Rep_traite "" f
    while [ "$Retour_Scrut" != "" ]; do
         echo "$Retour_Scrut"
         Scrut_Rep $Rep_traite "$Retour_Scrut" f
    done
    Sur Solaris, ça va m'afficher la liste des fichiers du répertoire et on sort du while.
    Par contre sous Linux, il va tourner indéfiniment dans la boucle et afficher indéfiniment le nom du dernier fichier présent.

    J'ai du mal à piger la logique de la fonction à vrai dire, je comprend pas le index($0,"/")!=0 par exemple, je sais que ça retourne la position du premier / mais pourquoi utiliser ça.

    Enfin j'ai planché la dessus quelques heures déjà et impossible de trouve pourquoi le comportement est différent sous Linux. Après il y a d'autres moyens de faire la même chose mais j'ai envie de comprendre ^^

    Peut-être que quelqu'un aura une idée géniale...

  2. #2
    Membre éclairé Avatar de BlaireauOne
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    492
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mars 2007
    Messages : 492
    Points : 652
    Points
    652
    Par défaut Afficher les fichiers d'un répertoire en ignorant les sous-répertoires
    Bonsoir,

    Pour ce que j'en comprends, il s'agit d'afficher les fichiers d'un répertoire en omettant les sous-répertoires et les fichiers de ces sous-répertoires.

    C'est une façon de faire très lourde et compliquée
    Pour que ça fonctionne, j'ai corrigé comme suit :
    -v PREC="$2"
    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
     
    Retour_Scrut=`find $1 -type $3 | sed -e "s/$Sub_scrut//" | awk -v PREC="$2" '
    {
    	# Autre appel de la fonction que le 1er appel
    	if (PREC != "" ) 
    		{
    		# Omission des fichiers deja traites lors des precedents appels de la fonction
    		while ( $0!=PREC && getline == 1 ) ;
    		      getline
    		}
     
    	while ( index($0,"/")!=0) 
    	{
    		# Detection et omission des repertoires
    		getline
    	}
    	print $0
    	exit  
    }' `
    }
    Loi de Murphy:
    La Théorie c'est quand ça ne marche pas mais que l'on sait pourquoi.
    La Pratique c'est quand ça marche mais qu'on ne sait pas pourquoi.
    Quand la théorie rejoint la pratique ça ne marche pas et on ne sait pas pourquoi.

  3. #3
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 280
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 280
    Points : 12 729
    Points
    12 729
    Par défaut
    Bonjour,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    # on remplace dans le path de scrutation '/' par '\/'
    Sub_scrut=`echo $1 | sed -e "s/\/$//" -e "s/$/\//" | sed -e "s/\//\\\\\\\\\//g"`
    Ici, le commentaire n'est pas complet, on remplace les '/' par '\\/' et surtout on s'arrange pour que la fin du répertoire soit '\\/', ceci est important pour la suite:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find $1 -type $3 | sed -e "s/$Sub_scrut//
    Ici, pour tout les fichier trouver par find, on retire le nom complet du répertoire ('/' de fin compris), ce qui fait que lorsque l'on trouve un '/' dans la liste, cela veut dire que l'on a bien un fichier mais qui ne se trouve pas dans le répertoire scanné mais dans un de ces sous-répertoire.

    Coté awk, un petit commentaire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if (PREC != "" ) 
    	{
    	# Omission des fichiers deja traites lors des precedents appels de la fonction
    	while ( $0!=PREC && getline == 1 ) ;
    	      getline
    	}
    Ici l'indentation est fausse et prête à confusion, le 2ème getline ne fait pas partie de la boucle while mais uniquement du corps du if.

    Bon maintenant, coté correctif, en fait, je pense que la différence est liée au find de linux et solaris, car comme c'est le cas sous linux, si le find ne rajoute pas une ligne vide finale, alors cela boucle indéfiniment et je pense que le find de solaris en rajoute un (pur spéculation, je ne peux actuellement pas le vérifier).

    Pour le tester sous linux, il suffit de remplacer:
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (find $1 -type $3 && echo)
    Mais le mieux est de rajouter une vrai vérification, et donc de remplacer:
    par:
    Cordialement.

  4. #4
    Nouveau Candidat au Club
    Homme Profil pro
    Inscrit en
    Janvier 2014
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2014
    Messages : 2
    Points : 1
    Points
    1
    Par défaut
    Merci à vous deux pour les infos, je vais tester ça et faire un retour.

Discussions similaires

  1. Réponses: 15
    Dernier message: 04/09/2014, 15h41
  2. Réponses: 4
    Dernier message: 16/08/2013, 11h25
  3. [Débutant] appeler une fonction à partir d'un répertoire
    Par miss_angel dans le forum Images
    Réponses: 2
    Dernier message: 01/11/2010, 23h39
  4. Fonctions permettant la copie d'un répertoire
    Par benj63 dans le forum C++Builder
    Réponses: 6
    Dernier message: 17/06/2004, 08h41

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