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 d'une chaine en fonction d'une autre


Sujet :

Shell et commandes GNU

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 162
    Par défaut Extraction d'une chaine en fonction d'une autre
    Bonjour,

    J'ai un fichier qui ce présente de la facon suivnte:
    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
     
    Standard
    .....
    Standard 
    .....
    Optimized
    ....
    Standard
    ...
    ...
    Standard
    .....
    .....
    .....
    Optimized
    ....
    Standard
    Où j'ai nombre inconnu de Standard et où je veux récupérer uniquement le Standard précédé d'un Optimized. les autres ne présentant pas d’intérêt pour moi.
    Mais après recherche j'ai pas trouver comment faire, et la recherche s'avère compliqué puisque je n'ai aucune idée de quel type de commande est impliquée. Je n'ai jamais appris à coder ou programmer je fais ça sur le tas.

    Personnellement j'ai penser faire une recherche sur Optimized et récupèrerais le numéro de la ligne de là je ferai une recherche sur sur Standard et je ne prendrai que la première sortie.
    Y a t il quelque chose de plus court du genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if Optimized then get 1er standard suivant
    .

  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,

    A tester...

    J'ai numéroté les "Standard" et si j'ai tout bien compris, seuls les 3 et 5 nous intéressent :

    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
    $ cat plop 
    Standard 1
    .....
    Standard 2
    .....
    Optimized
    ....
    Standard 3
    ...
    ...
    Standard 4
    .....
    .....
    .....
    Optimized
    ....
    Standard 5
    ...
     
    $ sed -n '/Optimized/{:z;n;/Standard/! bz;p;b}' plop 
    Standard 3
    Standard 5
     
    $

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 162
    Par défaut
    Euh tu pourrais m'expliquer un peu comment marche la commande.
    Et sinon il y a moyen de connaitre la ligne où l'itération apparait ?

  4. #4
    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
    -n
    L'option "-n" de la commande "sed" permet de n'afficher les lignes que sur demande, conjointement avec le flag "p" (voir plus loin)


    /Optimized/
    On recherche le motif placé entre les 2 slashs


    {
    Début du regroupement de commandes. Seules les commandes situées entre les 2 accolades seront appliquées au motif.


    :z
    On définit une étiquette. Les deux points étant l'instruction, "z" le nom donné à l'étiquette


    n
    Commande next. Le motif étant trouvé on charge la ligne suivante dans l'espace de travail


    /Standard/!
    Si la ligne ne contient pas le motif (le "!" étant le signe de la négation)


    bz
    On se branche à l'étiquette "z" avec la commande "b" (branchement) et on charge une nouvelle ligne


    p
    Sinon (le motif étant trouvé), on imprime la ligne sur la sortie standard


    b
    On se branche à la fin du script.


    }
    Fin du regroupement de commandes.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 162
    Par défaut
    Pour être sur d'avoir bien compris.
    On fait une recherche sur Optimized.
    Quand on le trouve on débute une nouvelle recherche (une boucle ?).
    l'étiquette c'est quoi, l'endroit où débute la nouvelle commande, le repère où commence la boucle ?
    là on charge la ligne juste après Optimized et si elle n'est pas égale à Standard on charge la suivante et ainsi de suite. Lorsque l'on a trouvé Standard on sort de cette boucle pour reprendre la recherche primaire.

  6. #6
    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 Erlen Voir le message
    Pour être sur d'avoir bien compris.
    On fait une recherche sur Optimized.
    Oui.

    Citation Envoyé par Erlen Voir le message
    Quand on le trouve on débute une nouvelle recherche (une boucle ?).
    D'abord on charge la ligne suivante, puis on boucle si le nouveau motif n'est pas trouvé.

    Citation Envoyé par Erlen Voir le message
    l'étiquette c'est quoi, l'endroit où débute la nouvelle commande, le repère où commence la boucle ?
    C'est un repère qu'on pose afin de s'y brancher après un test pour y exécuter les commandes qui suivent ladite étiquette.

    Citation Envoyé par Erlen Voir le message
    là on charge la ligne juste après Optimized et si elle n'est pas égale à Standard on charge la suivante et ainsi de suite.
    Exactement.

    Citation Envoyé par Erlen Voir le message
    Lorsque l'on a trouvé Standard on sort de cette boucle pour reprendre la recherche primaire.
    Tout à fait, mais avant on imprime la ligne sur la sortie standard, commande "p".

  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
    On peut faire comme ça aussi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -n '/Optimized/,/Standard/{/Optimized/b;/Standard/p}'
    On recherche l'intervalle de lignes compris entre les 2 motifs /Optimized/,/Standard/, on délaisse le 1er motif /Optimized/b mais on imprime le second /Standard/p.


  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 162
    Par défaut
    Merci pour toutes ces informations.

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 162
    Par défaut
    J'ai une question similaire :
    si on veut faire l'inverse, c'est à dire récupérer standard que quand il est suivit de Optimized.
    J'ai essayé d'utiliser la méthode zipe31 en inversant mais ça ne marche pas il sort tous les standard.

  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
    Tout dépend de comment est défini le "suivit" ???

    sed demande bien souvent à être adapté au cas par cas, donc sans un exemple concret, difficile de répondre

  11. #11
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 162
    Par défaut
    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
     
    Standard 1
    .....
    Standard 2
    .....
    Standard 3
    .....
    Optimized
    ....
    Standard 4
    ...
    ...
    Standard 5
    .....
    .....
    .....
    Optimized
    ....
    Standard 6
    ......
    Optimized
    Dans le cas ici ça serait de récupérer les lignes standard 3 5 6, car elles sont suivit par un Optimized.
    Alors que Standard 1 il y a 2 puis 3 avant Optimized.

  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
    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
    $ cat plop
    Standard 1
    .....
    Standard 2
    .....
    Standard 3
    .....
    Optimized
    ....
    Standard 4
    ...
    ...
    Standard 5
    .....
    .....
    .....
    Optimized
    ....
    Standard 6
    ......
    Optimized
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $ sed -n ':z;/Standard/h;n;/Optimized/!bz;g;p' plop 
    Standard 3
    Standard 5
    Standard 6
     
    $
    #n
    Affichage sur demande

    :z
    Étiquette

    /Standard/ h
    Si le motif est trouvé on le place dans la mémoire secondaire (commande "h") en écrasant son contenu

    n
    On passe à la ligne suivante

    /Optimized/ !b z
    Si le motif n'est pas trouvé (!), on boucle (bz)

    g
    Par contre s'il est trouvé, on écrase le contenu de la mémoire principale par celui de la mémoire secondaire, qui rappelons-le contient la dernière ligne rencontrée contenant le motif Standard.

    p
    Et on l'imprime à l'écran

  13. #13
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 162
    Par défaut
    Alors,

    Une dernière chose comment fait-on pour imprimer la ligne ou standard apparait ?
    Dans la précédente version
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -n '/Optimized/{:z;n;/Standard/! bz;p;b}' plop
    J'avais modifier le p par = et il me donnait le numéro de la ligne ou Standard était trouvé.
    Si je fait ça avec la version
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -n ':z;/Standard/h;n;/Optimized/!bz;g;=' plop
    La sortie est le numéro de la ligne où Optimized est trouvé.

  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
    On ne peut pas directement, du fait qu'on affiche la ligne qui est dans la mémoire annexe, alors que sed a en mémoire principale le numéro de la ligne qui contient "Optimized".

    Il faut utiliser un comptage extérieur (cat -n ou nl) et enfin récupérer ce qui nous intéresse...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $ sed -n ':z;/Standard/h;n;/Optimized/!bz;g;s/\s\+\([^\t]*\).*/\1/p' < <(cat -n plop)
    5
    12
    18
     
    $

  15. #15
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 162
    Par défaut
    Je crois que je vais renoncer au comment ça marche.
    En tout cas ça marche bien, j'ai juste un soucis. Au début j'ai juste le numéro de la ligne mais quand ça dépasse 100000 j'ai le numéro de la ligne l'objet de la recherche collé
    91023
    151694Standard
    161256Standard

  16. #16
    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
    Modifies la substitution comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    s/\s\+\([[:digit:]]*\).*/\1/

  17. #17
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 162
    Par défaut
    Ok merci, c'est parfait.

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

Discussions similaires

  1. Réponses: 0
    Dernier message: 26/11/2012, 12h04
  2. Réponses: 2
    Dernier message: 03/07/2009, 14h35
  3. [Mail] Extraction d'un nom d'image dans une chaine
    Par TmR14 dans le forum Langage
    Réponses: 4
    Dernier message: 18/01/2007, 09h38
  4. random en fonction d'une chaine de caractere
    Par tatayoyo dans le forum C
    Réponses: 6
    Dernier message: 28/02/2006, 21h23
  5. Réponses: 5
    Dernier message: 02/01/2006, 22h16

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