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

Unix Discussion :

Récupérer la valeur d'une ligne dans une varaible


Sujet :

Unix

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 68
    Points : 47
    Points
    47
    Par défaut Récupérer la valeur d'une ligne dans une varaible
    bonjour et bonne année à tous

    J'ai un fichier qui me fait une extraction de plusieurs jobs et donc je me retourve avec x fois le même pavé de ligne :

    fic.txt
    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
     Job full details for order number:00024zom
    Jobname: TOTO
    File Name: TOTO.KSH
    Application: DTOTO
    HostGroup:server3
    File Path : /kljsfkljqsfkl/fsfsdF/dfsd
     Job full details for order number:00024zop
    Jobname: TITI
    File Name: TITI.KSH
    Application: DTITI
    HostGroup:server1
    File Path : /fsdfsdf/sdfsdfsd/sdfsdfs
     Job full details for order number:000259rp
    Jobname: TUTU
    File Name: TUTU.KSH
    Application: TITI
    HostGroup:server2
    File Path : /fsdfsdf/sdfsdfsdf/SDFsdfsdf
    Mon fichier fait fprès de 3500 lignes avec toujours le même groupe de 6 lignes (Job full details for order number,Jobname,File Name,Application,HostGroup,File Path)

    Je voudrais à chaque fois que je trouve la ligne contenant le mot "order" qu'il me récupère la valuer juste après les ":" et ça pour la ligne contenant le "order" ainsi que les 5 qui suivent et ainsi de suite pour avoir un résultat après mise en forme qui soit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    00024zom:server3:/kljsfkljqsfkl/fsfsdF/dfsd/TOTO.KSH:DTOTO:TOTO
    00024zop:server1:/fsdfsdf/sdfsdfsd/sdfsdfs/TITI.KSH:DTITI:TITI
    ...
    J'espère que l'un de vous porra m'aiguiller, en attendant je retourne chez mon ami google pour étudier diverses pistes.

    Merci d'avance.

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

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

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    une façon de faire c'est que dès qu'on voit passer une ligne intéressante on positionne une variable et sur la dernière ligne on affiche la concaténation des différentes variables, évidement faut être absolument certain que les blocs de lignes sont rigoureusement les mêmes tout le long, sinon on risque de fausser le résultat potentiellement

    awk fait ça très bien :
    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
    30
    31
    32
    awk -F': ?' '
    /^ Job/ {
    	p1=$2;
    	next;
    }
     
    /^HostGroup/ {
    	p2=$2;
    	next;
    }
     
    /^File Path/ {
    	p3=$2;
    	printf("%s:%s:%s/%s:%s:%s\n",p1,p2,p3,p4,p5,p6);
    	p1=p2=p3=p4=p5=p6="";
    	next;
    }
     
    /^File Name/ {
    	p4=$2;
    	next
    }
     
    /^Application/ {
    	p5=$2;
    	next;
    }
     
    /^Jobname/ {
    	p6=$2;
    	next;
    }' fichier
    donc déroulé on voit clairement le principe, à chaque fois qu'on reconnait un motif on prend la 2e partie de la ligne qui nous intéresse, ça grâce à l'option -F': ?' qui définit un délimiteur de champs basé sur une regex, en l'occurrence les : suivi d'un espace optionnel

    à l'arrivée ça fait un truc un peu long/crado mais ca tient en une ligne si besoin :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ awk -F': ?' '/^ Job/ {p1=$2; next} /^HostGroup/ {p2=$2; next} /^File Path/ {p3=$2; printf("%s:%s:%s/%s:%s:%s\n",p1,p2,p3,p4,p5,p6); p1=p2=p3=p4=p5=p6=""; next} /^File Name/ {p4=$2; next} /^Application/ {p5=$2; next} /^Jobname/ {p6=$2; next}' fichier
    00024zom:server3:/kljsfkljqsfkl/fsfsdF/dfsd/TOTO.KSH:DTOTO:TOTO
    00024zop:server1:/fsdfsdf/sdfsdfsd/sdfsdfs/TITI.KSH:DTITI:TITI
    000259rp:server2:/fsdfsdf/sdfsdfsdf/SDFsdfsdf/TUTU.KSH:TITI:TUTU

  3. #3
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 858
    Points : 6 556
    Points
    6 556
    Par défaut
    Une version sed, c'est bourrin mais ça marche:
    Code sed mode basique : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -n '/order/{s/[^:]*://;N;N;N;N;N;s~\n[^:]*: *\(.*\)\n[^:]*: *\(.*\)\n[^:]*: *\(.*\)\n[^:]*: *\(.*\)\n[^:]*: *\(.*\)~:\4:\5/\2:\3:\1~g;p}' fic.txt
    ou
    Code sed mode étendu : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -nr '/order/{s/[^:]*://;N;N;N;N;N;s~\n[^:]*: *(.*)\n[^:]*: *(.*)\n[^:]*: *(.*)\n[^:]*: *(.*)\n[^:]*: *(.*)~:\4:\5/\2:\3:\1~g;p}' fic.txt

    L'option -n permet de ne pas faire d'affichage systématique des lignes.

    Quand "order" est détecté, le scénario est:
    • On remplace le début de la ligne jusqu'à ":" inclus par rien.
    • On ajoute les 5 lignes suivantes au pattern space.
    • on remplace les 5 lignes en plaçant les captures (qui commencent après les deux points suivis d'espaces éventuels, jusqu'à la fin de la ligne) dans l'ordre voulu.


    La commande p affiche le pattern space.

    NB: pour plus de rigueur on peut encadrer "order" avec des word boundaries: sed -n '/\<order\>/{s.....

    Une version Bash:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #!/bin/bash
     
    re=\\border\\b
    while read line
    do
    	if [[ $line =~ $re ]]; then
    		a=(${line#*:})
    		for i in {1..5}; do
    			read line 
    			a+=(${line#*:})
    		done
    		echo ${a[0]}:${a[4]}:${a[5]}/${a[2]}:${a[3]}:${a[1]}
    	fi
    done
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 68
    Points : 47
    Points
    47
    Par défaut
    Un très grand merci à vous deux, vous m'avez évité de continuer à chercher dans le vent et surtout à mieux comprendre la logique du AWK et du SED.

    Ca fonctione à merveille

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

Discussions similaires

  1. Récupérer une information d'une ligne dans une table
    Par Lebas dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 12/04/2013, 10h24
  2. Réponses: 4
    Dernier message: 15/10/2009, 13h33
  3. [MySQL] inserer une ligne d'une table dans une autre table
    Par piero53 dans le forum PHP & Base de données
    Réponses: 5
    Dernier message: 14/12/2008, 18h29
  4. Réponses: 2
    Dernier message: 30/10/2008, 13h28
  5. Réponses: 3
    Dernier message: 29/01/2008, 12h08

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