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 :

Récuperation complexe d'informations (grep,awk,cut,sed,find)


Sujet :

Shell et commandes GNU

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2016
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2016
    Messages : 7
    Par défaut Récuperation complexe d'informations (grep,awk,cut,sed,find)
    Bonjour, je suis débutant dans tout ça, et je galère depuis 2jours en stage et j'aimerais un peu d'aide si possible.

    Je m'explique, avec un nom d'Hôte connu je dois recuperer les information sur cet hôte dans un fichier qui contient une centaine d'Hôtes

    le fichier /etc/../../hosts.cfg se prèsente comme ceci:

    define host {
    host_name SW_nom (le nom que je connais a la base)
    addresse 0.0.0.0
    parents FW_nom
    ....
    ...
    }

    Je dois donc récupérer dans un variable ou un fichier tout le bloc se situant entre les { } mais dont le nom d'Hôte (host_name) est SW_nom..
    Et déjà là je bloque.

    Ensuite dans cette variable ou fichier, le dois récuperer la ligne "parents FW_nom" dans un autre variable ou fichier (ici la commande grep est assez facile pour ça).

    Mais ensuite sa se complique de nouveau:

    Dans " parents FW_nom" je dois recupérer le "FW_nom" dans une autre variable en sachant qu'il commence obligatoirement par "FW_" cependant il y as des espaces au début et au millieu de la ligne dont le nombre peut varier.
    J'ai essayé avec la commande cut mais je ne connais pas du tout les symboles et tout, enfin je n'ai pas réussis du tout quoi


    Ensuite je dois dans le même fichier hosts.cfg qu'au début, récuperer l'adresse IP de l'Hôte que je viens de recuperer juste avant dans le "parent" du premier Hôte ( donc recuperer l'adresse de l'Hôte FW_nom)

    J'espère avoir été assez clair, si vous voulez d'avantages d'informations n'hésitez pas.

    Je vous remercie d'avance car je n'avance pas du tout et je suis donc bloqué pour la suite de mon stage.

  2. #2
    Expert confirmé Avatar de frp31
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Juillet 2006
    Messages
    5 196
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juillet 2006
    Messages : 5 196
    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
    francois@baal:~$ cat > toto
    define host {
    host_name SW_nom (le nom que je connais a la base)
    addresse 0.0.0.0
    parents FW_nom
    ....
    ...
    }
    francois@baal:~$
    francois@baal:~$ var=$(sed '/define/,/\}/ !d ; /addresse/ !d ; s/.*\ //' toto)
    francois@baal:~$ echo $var
    0.0.0.0
    francois@baal:~$ unset var ; rm toto
    francois@baal:~$
    var=$( ) charge la variable var par le resultat de la commande entre ()
    sed est UNE des solutions de manipulation de chaines (texte)

    /a/,/b/ !d veut dire ne rien supprimer entre le pattern a et le pattern b(selection du bloc quoi....)

    /adresse/ !d idem pour une ligne unique contenant le pattern

    et enfin s/.*\ // signifie substituer tout jusqu a l espace par rien (donc garder que l IP)

    donc pour ton cas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    var=$(sed '/host_name SW_nom/,/\}/ !d ; /addresse/ !d ; s/.*\ //' toto)
    suffit d adapter
    si tu veux catcher plusieurs infos
    tu peux
    garder le principe tout ramener a une ligne et enfin avec une variable tableau tu retrouve la bonne colonne

    style var[1] contient l IP var[2] contient le host etc....

  3. #3
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2016
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2016
    Messages : 7
    Par défaut
    Merci beaucoup !

    En plus avec les explications c'est parfait, sa évite de copier/coller bêtement

    Je vais me débrouiller avec ça, encore merci!

  4. #4
    Expert confirmé Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 041
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 041
    Par défaut
    salut,

    au risque de me planter, je pars du principe que le fichier hosts.cfg est celui-ci :
    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
    define host {
      host_name SW_name1
      addresse 0.0.0.0
      parents FW_nom1
    }
     
    define host {
      host_name SW_name2
      addresse 1.2.3.4
      parents FW_nom2
    }
     
    define host {
      host_name SW_name3
      addresse 5.6.7.8
      parents FW_nom3
    }
    on connait donc "name2" qui nous permet d'identifier le 2e bloc et on veut récupérer les valeurs de chaque ligne dans une variable
    via awk, on fait un script (c'est plus lisible qu'un long oneliner en l'occurrence mais dans l'absolu ça peut tenir sur une seule ligne) script.awk :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    $0 ~ NOM , /}/ {  # ici on reprend l'idée du pattern range expliqué plus haut par frp31
            if ($1 == "host_name") { swname = $2; next}  # et là on test nos variables, une par une
            if ($1 == "addresse")  { addr = $2; next }
            if ($1 == "parents")   { fwname = $2; next}
    }
    END {
            printf ("%s %s %s\n", swname, addr, fwname) # enfin on affiche les variables, dans l'ordre
    }
    on peut donc faire le shell script suivant ensuite :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #!/bin/bash
    MACHINE="name2"
    read SWNAME ADDR FWNAME <<< $(awk -vNOM=$MACHINE -f script.awk hosts.cfg )
    echo "machine : SW_$MACHINE"
    echo "address : $ADDR"
    echo "parents : FW_$FWNAME"
    et le résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ ./pouet.sh
    machine : SW_name2
    address : 1.2.3.4
    parents : FW_FW_nom2
    in fine, on peut résumer le tout à un unique script en rusant un peu et en faisant attention à échapper les \$0, \$1, \$2 etc. dans le heredocument :
    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
    #!/bin/bash
     
    # on definit la machine explicitement, ca pourrait aussi bien etre dans une boucle for...
    MACHINE="name2"
     
    # on remue la sauce pour pas qu'elle colle
    read SWNAME ADDR FWNAME <<< $(
    awk -vNOM=$MACHINE -f - fichier <<EOF
       \$0 ~ NOM , /}/ {
          if (\$1 == "host_name") { swname = \$2; next}
          if (\$1 == "addresse")  { addr = \$2; next }
          if (\$1 == "parents")   { fwname = \$2; next}
       }
       END {
          printf ("%s %s %s\n", swname, addr, fwname)
       }
    EOF
    )
     
    # et c'est pret a servir
    echo "machine : SW_$MACHINE"
    echo "address : $ADDR"
    echo "parents : FW_$FWNAME"

Discussions similaires

  1. Grep et Cut avec un test conditionnel
    Par vladimire dans le forum Shell et commandes GNU
    Réponses: 1
    Dernier message: 11/02/2008, 09h21
  2. Commande AWK ou SED pour modification données dans fichier
    Par desbrandesq dans le forum Shell et commandes GNU
    Réponses: 1
    Dernier message: 29/01/2008, 17h56
  3. Ne récuperer que les informations d'un mois précis
    Par eown dans le forum SQL Procédural
    Réponses: 4
    Dernier message: 17/12/2007, 18h25
  4. Réponses: 13
    Dernier message: 24/10/2006, 14h17
  5. [langage] awk et sed dans script perl
    Par scoti dans le forum Langage
    Réponses: 3
    Dernier message: 07/04/2003, 18h26

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