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 :

Extraire valeur d'un stream (regexp ?)


Sujet :

Shell et commandes GNU

  1. #1
    Membre confirmé
    Inscrit en
    Septembre 2006
    Messages
    104
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 104
    Par défaut Extraire valeur d'un stream (regexp ?)
    Bonjour,
    je continue dans mes question de débutants

    Lorsque j'appelle une url dans mon script (via curl) elle me renvoit un message xml.
    Dans ce xml, j'aimerais récup une infos, plus précisement la valeur entre <id>toto</id> pour que je puisse l'utiliser dans la suite de mon script

    J'ai cherché un peu, je suis tombé sur sed mais je trouve ça très complexe au premier abord (et j'ai pas trop de souci avec les regexp en général).

    Donc si vous avez la solution ou que vous pouvez me guider...

    Merci

  2. #2
    Membre très actif

    Homme Profil pro
    Responsable projets techniques
    Inscrit en
    Février 2003
    Messages
    980
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Responsable projets techniques
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2003
    Messages : 980
    Par défaut
    J'ai une réponse de noob, mais il y a sûrement plus propre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -n 's/.*<id>\(\w*\)<\/id>.*/\1/p'
    -n
    > pour ne pas afficher les lignes

    s/.../.../ (s/.*<id>\(\w*\)<\/id>.*/\1/p)
    > chercher le pattern compris entre les 2 premiers slashs et le remplace par le contenu entre les 2 derniers slashs

    .*<id>\(\w*\)<\/id>.*
    > texte chercher : quelque chose ou pas, suivi de <id>, puis d'un mot (\w est à adapter) (les parenthèses échappées sont uniquement là pour mémoriser cette partie) puis suivi de </id> et d'éventuellement quelque chose

    \1
    > fait référence au premier groupe de parenthèses du pâté (.*<id>\(\w*\)<\/id>.*)précédent

    p
    > affiche la ligne correspondante

    Donc la commande cherche une ligne correspondant à quelque chose ou pas, suivi de <id>, puis d'un mot puis terminé par </id> et éventuellement autre chose. Elle remplace cette ligne par ce qui est entre <id> et </id> et affiche le résultat...

  3. #3
    Membre confirmé
    Inscrit en
    Septembre 2006
    Messages
    104
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 104
    Par défaut
    Réponse très rapide, merci bien

  4. #4
    Membre très actif

    Homme Profil pro
    Responsable projets techniques
    Inscrit en
    Février 2003
    Messages
    980
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Responsable projets techniques
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2003
    Messages : 980
    Par défaut
    de rien ^^ tu peux cliquer sur résolu si c'est ok, à moins que tu ne préfères attendre une réponse plus jolie (ce qui devrait être possible )

  5. #5
    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
    Citation Envoyé par Alek-C Voir le message
    à moins que tu ne préfères attendre une réponse plus jolie (ce qui devrait être possible )
    Salut,

    Plus jolie peut être pas mais j'ai plus coutume de faire comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -n 's/.*<id>\(\[^<]*\)<.*/\1/p'

  6. #6
    Membre confirmé
    Inscrit en
    Septembre 2006
    Messages
    104
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 104
    Par défaut
    Je continue avec le sed
    Là je cherche à obtenir le nom du rep du fichier (donc 56) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    dirname ftp/56/toto.zip | sed -n 's/*\/\(\w\)$/\1/p'
    (n'importe quoi * suivi de slash \/ suivi d'un mot \(w\) suivi de la fin de ligne - pour que si jamais dirname me renvoi alphonse/ftp/56 je n'ai pas ftp/56 dans \1)

    Et cela ne me renvoi rien donc pas pratique pour trouver l'erreur

    Une idée ?

  7. #7
    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,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    dirname ftp/56/toto.zip | sed 's#.*/##'


    Sinon, sans sed :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $ basename $(dirname ftp/56/toto.zip)

  8. #8
    Membre très actif

    Homme Profil pro
    Responsable projets techniques
    Inscrit en
    Février 2003
    Messages
    980
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Responsable projets techniques
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2003
    Messages : 980
    Par défaut
    "n'importe quoi" c'est .* et pas * tout seul
    * signifie : le caractère précèdent répété 0 ou plusieurs fois
    . signifie n'importe quel caractère (sauf fin de ligne selon les options)

    \w correspond à un seul caractère, donc si tu veux pouvoir en capturer plusieurs, il te faut une * derrière : \w*

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    dirname ftp/56/toto.zip | sed -n 's/.*\/\(\w*\)$/\1/p'
    Après, tu n'as pas besoin de dirname et d'une "capture" dans sed: dirname isolant la partie "dossier", il suffit que tu vires le début ! De plus, inutile ici d'utiliser le -n et le p puisque tu n'as qu'une seule ligne (ces deux options servent uniquement à ne pas afficher toutes les lignes, mais ici, tu n'as qu'une ligne, elles sont donc inutiles).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    dirname ftp/56/toto.zip | sed 's/.*\///'
    ou plus lisible (les / peuvent être remplacées par d'autres caractères):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    dirname ftp/56/toto.zip | sed 's#.*##'
    Sinon, tu peux utiliser les options de bash:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    fichier="ftp/56/toto.zip"
    dossier=${fichier%/*}
     
    echo ${dossier##*/}
    ${fichier%/*} > supprime la plus petite partie à droite de $fichier qui ressemble à /* (un slash suivi de n'importe quoi, ici, pas de . !!)
    ${dossier##*/} > supprime la plus grande partie à gauche de $dossier qui ressemble à */ (n'importe quoi se terminant par slash)

  9. #9
    Membre confirmé
    Inscrit en
    Septembre 2006
    Messages
    104
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 104
    Par défaut
    Plein de réponses, merci bien

  10. #10
    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
    Citation Envoyé par Alek-C Voir le message
    * signifie : le caractère précèdent répété 0 ou plusieurs fois
    En fait non, ce n'est pas le caractère précédent répété, mais une séquence de zéro, une ou plusieurs occurrence(s) de l'expression précédente.

    Quand tu dis "le caractère précédent répété 0 ou plusieurs fois", cela sous-entends qu'il doit être présent au moins une fois avant (enfin c'est ce que je comprends expliqué comme ça)

    \w correspond à un seul caractère, donc si tu veux pouvoir en capturer plusieurs, il te faut une * derrière : \w*
    Ce serait plutôt "n'importe quel caractère de la classe : [A-Za-z0-9_] (underscore _ compris)"


  11. #11
    Membre très actif

    Homme Profil pro
    Responsable projets techniques
    Inscrit en
    Février 2003
    Messages
    980
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Responsable projets techniques
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2003
    Messages : 980
    Par défaut
    Merci des précisions

    c'est vrai que j'ai cherché à raccourcir un peu trop mes explications et que du coup, ça n'en est pas forcément plus clair

    Cela dit, je trouve que "une séquence de zéro, une ou plusieurs occurrence(s) de l'expression précédente" peut également prêter à confusion !

    une séquence de zéro => 000000

    pas facile de définir le * sans exemple en fait...
    * indique que ce qui précède est absent ou présent, y compris plusieurs fois
    ?

    Sinon, pour le \w, là, aucun souci : je suis allé au plus court sans rentrer dans les détails, et ta définition est juste (mais ne parle pas forcément à quelqu'un qui ne connaît pas du tout les regexps), donc pour traduire :
    \w regroupe les lettres a à z (en minuscule) et A à Z (en majuscule) ainsi que les chiffres 0 à 9 et le caractère _ (underscore)

  12. #12
    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
    C'est clair que le plus dur dans les regex tout compte fait, c'est de les expliquer clairement

  13. #13
    Membre confirmé
    Inscrit en
    Septembre 2006
    Messages
    104
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 104
    Par défaut
    (re)Bonjour
    Est ce que qqun pourrait m'expliquer : sed 's#.*/##' ?
    Je ne comprend pas les #
    Et là j'essaye de recupérer le rep précédent et je n'y arrive pas
    dans /toto/coco/pouet/test.zip, récupérer la valeur de "coco"

    Merci

  14. #14
    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
    Citation Envoyé par Sylver--- Voir le message
    (re)Bonjour
    Est ce que qqun pourrait m'expliquer : sed 's#.*/##' ?
    Je ne comprend pas les #
    Par défaut le séparateur pour la commande de substitution (s) est le slash (/). Quand on retrouve ce caractère dans le motif à substituer (ou à rechercher), 2 choix s'offrent à nous.
    Soit on échappe le caractère, mais bien souvent ça devient vite illisible et laborieux, soit on change de caractère séparateur en en choisissant un qui ne soit pas contenu dans le motif à substituer, comme le dièse (#) dans ce cas. Mais on aurait pu mettre n'importe quoi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    sed 's|.*/||'
    sed 's,.*/,,'
    sed 'sA.*/AA'     #(si le motif ne contient que des minuscules)
    etc.



    Et là j'essaye de recupérer le rep précédent et je n'y arrive pas
    dans /toto/coco/pouet/test.zip, récupérer la valeur de "coco"

    Merci
    Là il faut jouer avec les références arrières.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $ echo "/toto/coco/pouet/test.zip" | sed 'sA/[^/]*/\([^/]*\).*A\1A'
    coco
    $

  15. #15
    Membre très actif

    Homme Profil pro
    Responsable projets techniques
    Inscrit en
    Février 2003
    Messages
    980
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Responsable projets techniques
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2003
    Messages : 980
    Par défaut
    Si tu commences à vouloir récupérer des répertoires parents, tu peux aussi réfléchir à utiliser autre chose que sed selon le besoin (awk, cut, perl, ...) parce qu'il y a un moment où la lecture devient ardue comme le montre l'exemple de zipe31

    (edit) avec awk, ça donnerait ceci par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ echo "/toto/coco/pouet/test.zip" | awk -F/ '{print $(NF-2)}'
    coco
    NF indiquant le dernier champ, NF-1 te renvoie le dernier dossier et NF-2 l'avant dernier (etc...)

    Tu as aussi des fonctions intégrées à bash:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $ export test="/toto/coco/pouet/test.zip"
    $ echo ${test%/*/*}
    /toto/coco
    Après, tout dépend de ce que tu cherches à en faire !

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

Discussions similaires

  1. [VB.net] Extraire valeur max d'un tableau
    Par grand_prophete dans le forum Windows Forms
    Réponses: 9
    Dernier message: 29/03/2011, 17h37
  2. Manipuler tableaux pour extraire valeur
    Par Lafab dans le forum Langage
    Réponses: 2
    Dernier message: 24/09/2008, 16h40
  3. [Tableaux] Extraire valeur d'une chaine de caractere
    Par Shandler dans le forum Langage
    Réponses: 10
    Dernier message: 20/03/2008, 10h57
  4. Réponses: 2
    Dernier message: 02/10/2007, 11h42
  5. Extraire valeur de colonne
    Par Nounours1 dans le forum VBA Access
    Réponses: 2
    Dernier message: 02/07/2007, 21h38

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