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 :

Extraction de sous-chaine


Sujet :

Shell et commandes GNU

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 13
    Points : 8
    Points
    8
    Par défaut Extraction de sous-chaine
    Bonjour
    J'aimerai extraire d'une chaine (LD_LIBRARY_PATH) une sous chaine qui peut être g00 jusqu'à g99.

    Je fais pour le moment:
    set a=`expr $LD_LIBRARY_PATH : '\(g[0-9][0-9]\)'`
    J'aimerai récupérer dans a la valeur g10 si par exemple dans LD_LIBRARY_PATH il y avait toto/g10/titi/df292
    Merci d'avance de votre aide

  2. #2
    Membre éclairé 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 : 60
    Localisation : France

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

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

    Voici ce que j'obtiens (la chaîne g[[:digit:]]{2} peut apparaître plusieurs fois dans $LD_LIBRARY_PATH).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    echo $LD_LIBRARY_PATH | awk --posix -F ':' '
    {
        for (i = 1; i <= NF; i++)
        {
            pos = match($i, /g[[:digit:]]{2}/)
            if (pos != 0)
            {
                printf "%s\n", substr($i, pos, 3)
            }
        }
    }'
    Explications:
    Option --posix pour pouvoir utiliser [[:digit:]]{2} au lieu de répéter deux fois [[:digit:]].
    Recherche de la chaîne grâce à match(). Si trouvé (retour non nul), alors impression de la sous-chaîne.

    Si quelqu'un peut mieux faire, je suis curieux de voir comment (sed?).
    Un problème bien posé est déjà résolu (H. Bergson).

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 13
    Points : 8
    Points
    8
    Par défaut
    Ok merci beaucoup pour la réponse mais cela ne fonctionne pas chez moi, j'obtiens un ' sans correspondance.

  4. #4
    Membre éclairé 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 : 60
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2007
    Messages : 703
    Points : 823
    Points
    823
    Par défaut
    J'utilise Bash (echo $SHELL donne /bin/bash).
    Pour tester, j'ai fait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    a="/toto:/toto/g01/titi:/tata/tonton/g98"
    echo $a | awk --posix -F ':' '{for (i = 1; i <= NF; i++) {pos=match($i, /g[[:digit:]]{2}/); if (pos != 0) {printf "%s\n", substr($i, pos, 3)}}}'
    g01
    g98
    Quel est le problème exactement? Y a-t-il une erreur (le cas échéant laquelle?) ou la réponse n'est pas correcte?

    Peux-tu donner ta variable LD_LIBRARY_PATH, que j'essaie chez moi?
    Un problème bien posé est déjà résolu (H. Bergson).

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 13
    Points : 8
    Points
    8
    Par défaut
    Bonsoir,
    Je ne peux plus essayer vu que je n'aurai pas accès a la machine ou je fais le test d'ici le week-end prochain.
    En fait j'ai mi le code que tu m'as donné dans un .cshrc et je fais ensuite un source .cshrc
    J'obtiens à la suite de ce source dans le terminal le message: ' sans correspondance
    Je n'avais pas vu que le code que tu m'as donné est pour du bash (je ne connais pas grand chose au langage de shell).

  6. #6
    Membre éclairé 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 : 60
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2007
    Messages : 703
    Points : 823
    Points
    823
    Par défaut
    Ce n'est pas le même shell, effectivement. Cependant la différence ne devrait pas porter préjudice. Le problème que j'imagine est la manière de faire les retours à la ligne que j'ai faits. Il faudrait que tu essaies en ne mettant qu'une seule ligne, comme le dernier exemple que je t'ai fourni.

    Pour tester, tu peux mettre le script dans un fichier (fichier.script, par exemple), puis faire la commande chmod a+x fichier.script pour rendre ce fichier exécutable et enfin lancer le script par ./fichier.script. Il faudrait aussi ajouter une première ligne: #!/bin/bash, pour bien spécifier que l'on veut le shell Bash (ou #!/bin/csh si tu préfères csh); c'est le shebang. Bash est le plus courant sur Linux.
    Un problème bien posé est déjà résolu (H. Bergson).

  7. #7
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Points : 2 505
    Points
    2 505
    Par défaut
    csh n'a pas du tout la même syntaxe que les shells du genre sh, ksh, bash... Les deux ne sont absolument pas compatibles.

  8. #8
    Membre éclairé 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 : 60
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2007
    Messages : 703
    Points : 823
    Points
    823
    Par défaut
    C'est vrai Matafan, mais ici on a juste les deux commandes: echo $var | awk ... . Il n'y a que echo et le pipe '|' qui dépendent du shell, et leur fonctionnement est constant dans tous les shells. Pour le programme passé à awk, il ne dépend que de la commande awk qui est la même quel que soit le shell.

    Donc dans ce cas particulier, le type de shell ne devrait pas influencer le résultat.
    Un problème bien posé est déjà résolu (H. Bergson).

  9. #9
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 13
    Points : 8
    Points
    8
    Par défaut
    Bonsoir à tous,

    Désolée de répondre si tard mais je n'ai pas pu me connecter avant.
    Tout d'abord merci pour votre aide et vos réponses, ça m'a beaucoup aidée.

    J'ai fais le test aujourd'hui et ca marche très bien lorsque le code est sur une même ligne. J'ai fais le test dans mon fichier .cshrc (et ensuite source .cshrc) et aussi dans un script sh, si par exemple LD_LIBRARY_PATH contient /usr/local:toto/g45/titi:toto/g45/tata, ça m'affiche bien deux fois la chaine g45 dans la console.

    Maintenant j'aimerai ne pas afficher la chaine g45 mais plutôt l'affecter à une variable pour pouvoir tester cette valeur ensuite.
    Si je prends l'exemple de g45, LD_LIBRARY_PATH peut contenir plusieurs fois la chaîne g45. En fait, il faudrait récupérer la première occurence du type g[0-9][0-9] trouvée.

    Pour l'instant j'ai fais plusieurs tests mais je n'arrive pas à placer la chaine trouvée dans une variable. Si quelqu'un à une idée...

    Merci beaucoup d'avance

  10. #10
    Membre éclairé 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 : 60
    Localisation : France

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

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

    Pour n'afficher que la première occurence de g[[:digit:]]{2}, il faut ajouter un exit dans le if. Et pour mettre tout ça dans une variable, ça dépend du shell. En bash c'est var=$(...), mais en csh c'est, je crois, set var = `...`.
    On obtient donc...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    set var = `echo $LD_LIBRARY_PATH | awk --posix -F ':' '{for (i = 1; i <= NF; i++) {pos=match($i, /g[[:digit:]]{2}/); if (pos != 0) {printf "%s\n", substr($i, pos, 3); exit}}}'`
    Un problème bien posé est déjà résolu (H. Bergson).

  11. #11
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 13
    Points : 8
    Points
    8
    Par défaut
    Bonjour,

    Merci, c'est parfait ça marche! J'ai fais le test dans mon script sh.
    En fait, j'ai enlevé set, j'ai juste mis var = ` ...` parce-qu'avec set il n'y avait rien dans ma variable.

    Donc merci beaucoup

  12. #12
    Membre éclairé 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 : 60
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2007
    Messages : 703
    Points : 823
    Points
    823
    Par défaut
    S'il s'était agi d'un shell Bash, voici une commande un peu plus concise.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    var=$(echo "${LD_LIBRARY_PATH//[\/:]/$'\n'}" | awk --posix '/^g[[:digit:]]{2}$/ {print; exit}')
    Explications:

    • echo "...": la variable LD_LIBRARY_PATH est de la forme: /dir1/dir2:/dir3/dir4/dir5... Après transformation, les caractères '/' et ':' sont transformés en '\n', donc on obtient chaque dir sur une seule ligne. Attention, les double-quotes sont obligatoires pour éviter que la commande echo ne change les '\n' en espaces simples.
    • awk '...': recherche simple de g[[:digit:]]{2}, impression de la ligne entière puis sortie systématique.
    Un problème bien posé est déjà résolu (H. Bergson).

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

Discussions similaires

  1. Extraction de sous Chaines
    Par xenonex dans le forum Scripts/Batch
    Réponses: 2
    Dernier message: 11/12/2008, 15h10
  2. Extraction de sous chaines
    Par benjiprog dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 13/07/2007, 10h36
  3. Extraction de sous-chaine
    Par yansg dans le forum Shell et commandes GNU
    Réponses: 4
    Dernier message: 02/05/2007, 22h14
  4. Réponses: 7
    Dernier message: 06/09/2006, 15h10
  5. Extraction de sous-chaine dans une chaine
    Par ma2th dans le forum C
    Réponses: 7
    Dernier message: 07/05/2004, 12h42

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