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 :

Recherche à l'aide d'une fonction récursive


Sujet :

Shell et commandes GNU

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Futur Membre du Club
    Homme Profil pro
    Développeur Java
    Inscrit en
    Avril 2014
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Avril 2014
    Messages : 4
    Par défaut Recherche à l'aide d'une fonction récursive
    Salut,

    j'ai essayé de créer un script qui me permet de trouver la liste de tous les répertoires qui contiennent le fichier config. La recherche commence dans le répertoire passé en paramètre au script. La fonction rechercheRecursiveDossier parcourt les sous-répertoires (par ex. A B C D) du dossier passé en paramètre. Si le fichier config se trouve dans le sous-répertoires "A" la fonction n'ira pas chercher le fichier config dans les sous-répertoires de "A" mais elle passera au sous-répertoire "B". Si maintenant le répertoire "B" ne possède pas le fichier config alors la fonction va chercher dans les sous-répertoires de "B" et ainsi de suite.

    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
    27
    28
    29
     
    #!/bin/bash
     
    rechercheRecursiveDossier()
    {	 
    	for line in `find "$1" -mindepth 1 -maxdepth 1 -type d`
    	do
    		if verifDossier "$line" ;then
    			tabRep[${#tabRep[*]}]="$line"
    		else
    			tabTemp=$(rechercheRecursiveDossier "$repertoire")
    			tabRep=("${tabRep[@]}" "${tabTemp[@]}")
    		fi
    	done
     
    	echo "$tabRep"
    }
     
    verifDossier()
    {
    	if [ ! -f "$1/config" ] ;then
    		return 1
    	fi
    	return 0
    }
     
    n=$(rechercheRecursiveDossier $1)
     
    echo "$n"
    Et voici les erreurs que j'obtiens lorsque je teste mon script :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    find: impossible de chercher "": Aucun fichier ou dossier de ce type
    find: impossible de chercher "": Aucun fichier ou dossier de ce type
    find: impossible de chercher "": Aucun fichier ou dossier de ce type
    Si vous avez des idées, n'hésitez pas :p Ou bien si vous avez un autre moyen pour le faire.

    Merci d'avance

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 664
    Par défaut
    Bonjour,

    tout cela ne semble pas vraiment utile
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find "$1" -mindepth 1 -maxdepth 1 -type f -name 'config' -printf '%h\n'
    et hop !
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Développeur Java
    Inscrit en
    Avril 2014
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Avril 2014
    Messages : 4
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    Bonjour,

    tout cela ne semble pas vraiment utile
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find "$1" -mindepth 1 -maxdepth 1 -type f -name 'config' -printf '%h\n'
    et hop !
    Salut,

    le problème c'est que quand je fais un find je récupère tout les dossiers qui contiennent le fichier config. Même les sous-répertoires d'un répertoire qui contient le fichier config. Alors que je ne veux pas avoir ces sous-répertoires. En ce qui concerne la fonction verfiDossier, elle contiendra d'autre vérification : présence d'autres fichiers, bon formatage de certains d'entre eux, etc ...

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 664
    Par défaut
    quand je fais un find je récupère tout les dossiers qui contiennent le fichier config.[...]Alors que je ne veux pas avoir ces sous-répertoires.
    et quelle est la règle à appliquer ?

    présente-nous ta hiérarchie de dossiers/fichiers, et le résultat correspondant, que tu souhaites obtenir.
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  5. #5
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 361
    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 361
    Par défaut
    Bonjour,

    Ton erreur est sur la ligne suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tabTemp=$(rechercheRecursiveDossier "$repertoire")
    A aucun moment tu initialises la variable repertoire.

    Mais, N_BaH à raison, tu fais trop compliqué et cela risque d'être lent.

    Peux-tu donner un exemple de ce que tu veux obtenir comme liste et ce que te reourne comme liste la commande find que tu ne désire pas ?

  6. #6
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    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 840
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par disedorgue Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tabTemp=$(rechercheRecursiveDossier "$repertoire")
    A aucun moment tu initialises la variable repertoire.
    Bonjour
    Oui, je pense que ici il faut mettre la variable "$line"...

    Citation Envoyé par disedorgue Voir le message
    Peux-tu donner un exemple de ce que tu veux obtenir comme liste et ce que te reourne comme liste la commande find que tu ne désire pas ?
    D'après ce que j'ai compris, et surtout en lisant cette phrase "Même les sous-répertoires d'un répertoire qui contient le fichier config alors que je ne veux pas avoir ces sous-répertoires", je pense qu'avec une arborescence de ce type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    a
    |-- [-rw-r--r--]  a/config
    |-- [drwxr-xr-x]  a/x
    |   `-- [-rw-r--r--]  a/x/config
    |-- [drwxr-xr-x]  a/y
    |   `-- [-rw-r--r--]  a/y/config
    `-- [drwxr-xr-x]  a/z
        -- [drwxr-xr-x]  a/z/a
        |   `-- [-rw-r--r--]  a/z/a/config
        `-- [-rw-r--r--]  a/z/config
    Si le fichier "config" est trouvé dans un dossier (exemple a/config), alors il n'est plus recherché dans les sous-dossiers de "a" (donc ni dans a/x, ni dans a/y ni dans a/z)...

    Si c'est ça alors le code ci-dessous fait ce qui est demandé

    Code bash : 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
     
    rechercheRecursiveDossier()
    {	 
    	for f in "$1"/*; do
    		if verifDossier "$f" ;then
    			echo "$f"
    			return
    		fi
    	done
    	for f in "$1"/*; do
    		test ! -d "$f" && continue
    		res=$(rechercheRecursiveDossier "$f")
    		if test -n "$res"; then
    			echo "$res"
    			return
    		fi
    	done
     
    	echo ""
    }
     
    verifDossier()
    {
    	[ -f "$1" ] && return 0 || return 1
    }
     
    rechercheRecursiveDossier $1
    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]

  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
    Bonjour,

    Comme d'habitude, chacun réagira selon son optique:
    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
    $ mkdir a
    $ mkdir a/x a/y a/z
    $ mkdir a/z/a
    $ >a/config
    $ >a/x/config
    $ >a/y/config
    $ >a/z/config
    $ >a/z/a/config
    $ find a -name "config"
    a/y/config
    a/config
    a/x/config
    a/z/config
    a/z/a/config
    $ find a -name "config"|sed 's@config@.*/.*@g;'
    a/y/.*/.*
    a/.*/.*
    a/x/.*/.*
    a/z/.*/.*
    a/z/a/.*/.*
    Et la commande qui déchire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $ grep -v -f <(find a -name "config"|sed 's@config@.*/.*@g;') <(find a -name "config")
    a/config
    $

  8. #8
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    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 840
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    cependant, n devrait être un tableau, alimenté dans la fonction récursive.
    Ca dépend du besoin A-t-il besoin de traiter plusieurs fois la liste des dossiers ???

    Citation Envoyé par Flodelarab Voir le message
    Pourquoi un script pour si peu?
    Citation Envoyé par Phoenix89 Voir le message
    En ce qui concerne la fonction verfiDossier, elle contiendra d'autre vérification : présence d'autres fichiers, bon formatage de certains d'entre eux, etc ...
    Pour ça !!!
    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
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 664
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 664
    Par défaut
    un tableau permettra de préserver les noms de fichiers contenant des espaces, ou autres contenus dans l'IFS, alors qu'une variable, sans guillemets, ne le fera pas.
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 664
    Par défaut
    Code recursDir : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #!/bin/bash
     
    shopt -s globstar nullglob
    declare -A okDirs
     
    for f in dos/**
    do
       if test -f "$f/config"
       then
          test -z "${okDirs[${f%/*}]}" && { okDirs[$f]=1; echo "$f";} || continue
       fi  
    done
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $ ./recursDir
    dos/A/1/1
    dos/A/1/2/1
    dos/B
    dos/C/1
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

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

Discussions similaires

  1. Aide pour une fonction récursive.
    Par fred61 dans le forum Débuter
    Réponses: 13
    Dernier message: 21/01/2015, 08h39
  2. Réponses: 3
    Dernier message: 30/05/2014, 22h04
  3. Recherche de l'aide pour une Fonction OptionButton
    Par Au2laDeNosReves dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 20/03/2009, 21h59
  4. Réponses: 2
    Dernier message: 17/06/2008, 12h08
  5. Besoin d'aide sur une fonction
    Par PrinceMaster77 dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 30/08/2005, 17h40

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