Forum Programmation.shell Utilisation de awk pour la jointure de 2 fichiers

Posté par . Licence CC by-sa
2
21
jan.
2013

Je possède deux fichiers de taille différente ayant en commun un champ.
fichier 1:

1 48102
2 48103
3 48152
4 48156
5 48189

fichier 2:

14 jean
503 Benjamin
48102 Georges
48103 Lili
48152 Mélina
48156 Chantal
48189 Daniel
48512 Esthelle

Je souhaite réaliser un fichier final jointant ces 2 fichier le premier par le deuxième champ et le deuxième par son premier champ.

Mais essai avec join n'ont pas était concluant et il me semble que awk peut le faire donc si quelqu'un a une idée.

Merci d'avance

  • # join

    Posté par (page perso) . Évalué à 1. Dernière modification le 21/01/13 à 10:10.

    Ca passe pas avec join ??

    • [^] # Re: join

      Posté par . Évalué à 0.

      plusieurs tests mais les résultats obtenu ne sont pas concluant, comme si il commencé la jointure au milieu du fichier , je pense que c'est du au fait que les fichiers sont de taille différente et qu'il y a des trous dans mon champ de jointure.

    • [^] # Re: join

      Posté par . Évalué à 0.

      j'ai testé
      join -1 2 -2 1 -o 1.1 2.2 -i --nocheck-order fichier1 fichier 2

      résultat :
      4 Chantal
      5 Daniel

      • [^] # Re: join

        Posté par (page perso) . Évalué à 1.

        avec fichier2 sous cette forme ça passe :

        00014 jean
        00503 Benjamin
        48102 Georges
        48103 Lili
        48152 Mélina
        48156 Chantal
        48189 Daniel
        48512 Esthelle

        Nicolas

  • # Avec join un brin de fgrep et un soupçon de cut

    Posté par . Évalué à 1.

    Salut,

    $ join -1 2 -2 1 f1 <(fgrep -f <(cut -d ' ' -f 2 f1) f2)
    48102 1 Georges
    48103 2 Lili
    48152 3 Mélina
    48156 4 Chantal
    48189 5 Daniel
    
    

    ;-)

    • [^] # Re: Avec join un brin de fgrep et un soupçon de cut

      Posté par . Évalué à 0.

      j'obtient
      join: file 2 is not in sorted order
      join: file 1 is not in sorted order

      je ne comprend pas vraiment d'ou vient le probleme.

      • [^] # Re: Avec join un brin de fgrep et un soupçon de cut

        Posté par . Évalué à 0.

        j'ai tester en ajoutant a mon script un sort -r sur chacun de mes chier sur le champ de la jointure, mais le résultat est toujours le même .

        • [^] # Re: Avec join un brin de fgrep et un soupçon de cut

          Posté par . Évalué à 1.

          J'ai fait avec les exemples fournis de tes fichiers ;-\

          Ce qui donne :

          Le contenu des fichiers :

          $ cat f1
          1 48102
          2 48103
          3 48152
          4 48156
          5 48189
          
          $ cat f2
          14 jean
          503 Benjamin
          48102 Georges
          48103 Lili
          48152 Mélina
          48156 Chantal
          48189 Daniel
          48512 Esthelle
          
          

          Le résultat du "fgrep" qui sert juste à éliminer les enregistrements de "f2" qui ne sont pas présents dans "f1" :

          $ fgrep -f <(cut -d ' ' -f 2 f1) f2
          48102 Georges
          48103 Lili
          48152 Mélina
          48156 Chantal
          48189 Daniel
          
          

          Et le résultat final :

          $ join -1 2 -2 1 f1 <(fgrep -f <(cut -d ' ' -f 2 f1) f2)
          48102 1 Georges
          48103 2 Lili
          48152 3 Mélina
          48156 4 Chantal
          48189 5 Daniel
          
          

          $
          Si ça ne marche pas chez toi, il faut chercher ailleurs… système ? shell ? format des fichiers ? etc.

  • # Bizarre bizarre

    Posté par . Évalué à 1.

    Le truc un eu bizarre c'est que j'ai fait plusieurs jointures avec ta solution cependant une me résiste
    file 1:
    1 12:15:a5:45
    2 17:15:a5:d5
    3 12:ab:a5:a5
    41 00:15:25:a5
    42 18:14:a5:75

    file 2

    1 eth1
    2 eth10
    3 eth5
    4 eth6
    5 eth22

    40 eth8
    41 eth17
    42 eth9
    43 eth11

    une fois de plus il me dit que file 1 n'est pas trié, est ce a cause des trou ?

    • [^] # Re: Bizarre bizarre

      Posté par . Évalué à 1.

      Non ce n'est pas à cause des trous, mais des motifs (chiffres) et du fait que "fgrep" ne peut utiliser de regex.

      $ cut -d ' ' -f 1 f1
      1
      2
      3
      41
      42
      
      $ fgrep -f <(cut -d ' ' -f 1 f1) f2 
      1 eth1
      2 eth10
      3 eth5
      5 eth22
      41 eth17
      42 eth9
      43 eth11
      
      

      On ne peut pas dire à "fgrep" de ne tenir compte que des motifs présents en début de ligne :

      $ fgrep 1 f2
      1 eth1
      2 eth10
      41 eth17
      43 eth11
      
      

      Comme on pourrait le faire avec "grep" ou "egrep" :

      $ grep '^1' f2
      1 eth1
      
      
      • [^] # Re: Bizarre bizarre

        Posté par . Évalué à 1.

        je ne peut donc pas faire de jointure comme précédemment ?

      • [^] # Re: Bizarre bizarre

        Posté par . Évalué à 0.

        On ne peut pas dire à "fgrep" de ne tenir compte que des motifs présents en début de ligne

        Non, mais on peut lui dire de ne sélectionner que des mots entiers avec -w

        fgrep -w 1 f2
        1 eth1
        
        
        • [^] # Re: Bizarre bizarre

          Posté par . Évalué à 0.

          Exact, merci ;-)

          Honte à moi en plus je m'en suis servi dernièrement ;-(

    • [^] # Re: Bizarre bizarre

      Posté par . Évalué à 2.

      join ne fonctionne pas parce que dans tes deux cas fichier2 est trié numériquement alors que join utilise un ordre alphabétique (40 > 5 en ordre numérique mais "40" < "5" en ordre alphabétique).

      Pour ton exemple initial, la commande suivante fonctionne:

      sort fichier2 | join -1 2 -2 1 fichier1 -
      
      

      Et pour l'exemple avec les interfaces réseau:

      sort fichier2 | join -1 1 -2 1 fichier1 -
      
      
      • [^] # Re: Bizarre bizarre

        Posté par . Évalué à 0.

        serait il possible dans mes fichiers de remplacer dans le premier champ les 1,2,3,4,5,6,7,8,9 par 01,02,03,04,05,06,07,08,09?

  • # Avec Zsh

    Posté par . Évalué à 3.

    On déclare deux tableaux associatifs (on accède aux éléments par une clé plutôt que par un indice), puis on parcourt le premier fichier et on ajoute le dernier élément :

    typeset -A aa bb
    aa=( $(<$1) )
    bb=( $(<$2) )
    
    for k in ${(nk)aa} ; print $k $aa[$k] $bb[$aa[$k]]
    
    

    Ce qui nous donne :

    1 48102 Georges
    2 48103 Lili
    3 48152 Mélina
    4 48156 Chantal
    5 48189 Daniel
    
    

    On peut aussi parcourir le second fichier et remplacer les éléments manquants par « ? » :

    for k in ${(nk)bb} ; print ${(k)aa[(r)$k]:-\?} $k  $bb[$k]
    
    

    Ce qui nous donne :

    ? 14 jean
    ? 503 Benjamin
    1 48102 Georges
    2 48103 Lili
    3 48152 Mélina
    4 48156 Chantal
    5 48189 Daniel
    ? 48512 Esthelle
    
    
  • # Bon autant vous montrez le complet ça vous aidera peut etre

    Posté par . Évalué à 0.

     #!/bin/bash
     ########################################################################
    
     #Recuperation des addresse mac dans un fichier au format decimal et hexa
     snmpwalk -v 2c -c public -OX xxx.xxx.xxx.xxx 1.3.6.1.2.1.17.4.3.1.1 > /scriptsOID/mac1016.tmp
    
     #creation du fichier mac1016.dat contenant la relation mac hex / mac deci
     while read line;
     do echo -e ${line:29} >> /scriptsOID/mac1016b.tmp
     done < /scriptsOID/mac1016.tmp;
     awk -F " " '{ print $1,$4":"$5":"$6":"$7":"$8":"$9 }' /scriptsOID/mac1016b.tmp >>      /scriptsOID/mac1016.dat
    
    #recuperation du portbridge
    snmpwalk -v 2c  -c public -Of  xxx.xxx.xxx.xxx .1.3.6.1.2.1.17.4.3.1.2 > /scriptsOID/bridge.tmp
    
    #creation du fichier bridge.dat
    while read line;
    do echo -e ${line:44} >> /scriptsOID/bridgeb.tmp
    done < /scriptsOID/bridge.tmp
    awk -F " " '{ print $1,$4 }' /scriptsOID/bridgeb.tmp >> /scriptsOID/bridge.dat
    
    #recuperation du portID**
    snmpwalk -v 2c  -c public -Of  xxx.xxx.xxx.xxx .1.3.6.1.2.1.17.1.4.1.2 > /scriptsOID/portid.tmp
    
    #creation du fichier portid.dat
    while read line;
    do echo -e ${line:44} >> /scriptsOID/portidb.tmp
    done < /scriptsOID/portid.tmp
    awk -F " " '{ print $4,$1 }' /scriptsOID/portidb.tmp >> /scriptsOID/portid.dat
    
    #recuperation du port
    snmpwalk -v 2c  -c public -Of  xxx.xxx.xxx.xxx .1.3.6.1.2.1.31.1.1.1.1 >> port.tmp
    
    #creation du fichier port.dat
    while read line;
    do echo -e ${line:77} >> /scriptsOID/portb.tmp
    done < /scriptsOID/port.tmp
    awk -F " " '{ print $1,$4 }' /scriptsOID/portb.tmp >> /scriptsOID/port.dat
    
    #jointure entre les fichier .dat pour former un fichier unique servant de base de donnee
        #jointure de mac1016.dat et port bridge.dat pour former mac16bridge.dat
        join -1 1 -2 1 ./mac1016.dat <(fgrep -f <(cut -d ' ' -f 1 ./mac1016.dat) bridge.dat)> mac16bridge.dat
        awk -F " " '{ if ($3<49) print $3, $2} ' ./mac16bridge.dat > ./mac16bridge.tmp
        sort mac16bridge.tmp > mac.sort
    
        #jointure de portid.dat et port.dat pour former portname.dat
        join -1 1 -2 1 ./portid.dat <(fgrep -f <(cut -d ' ' -f 1 ./portid.dat) port.dat)>  portname.dat
        cut -d ' ' -f 2,3 ./portname.dat >portname.tmp
        awk -F " " '{ if ($1<49) print $1, $2} ' ./portname.tmp > ./portname.tmp2
        sort ./portname.tmp2 > ./portname.sort
    
        #jointure de mac16bridge.dat et portname.dat pour former le fichier final BD.dat
        join -1 1 -2 1 ./mac.sort <(fgrep -f <(cut -d ' ' -f 1 ./mac.sort) portname.sort)> BD.dat
    
    

    Pour le moment mon scripts ressemble à ça il sert a récupéré en SNMP les info d'un switch et à établir un tableau sous la forme :
    Adresse mac port ip du switch

    Mais la jointure me pose toujours problème.

    Mon scripts n'est pas très beau mais c'est plutôt nouveau tout ça pour moi .

    • [^] # Re: Bon autant vous montrez le complet ça vous aidera peut etre

      Posté par . Évalué à 3.

      On peut simplifier.

      Les boucles du style:

      while read line;
      do echo -e ${line:29} >> /scriptsOID/mac1016b.tmp
      done < /scriptsOID/mac1016.tmp;
      
      

      se simplifient en:

      cut -c29- < /scriptsOID/mac1016.tmp > /scriptsOID/mac1016b.tmp
      
      

      La récupération des mac peut se réécrire en remplaçant les fichiers intermédiaires par des pipes:

      snmpwalk -v 2c -c public -OX xxx.xxx.xxx.xxx 1.3.6.1.2.1.17.4.3.1.1 | \
      cut -c29- | \
      awk -F " " '{ print $1,$4":"$5":"$6":"$7":"$8":"$9 }' > /scriptsOID/mac1016.dat
      
      

      Comme en plus, il faut avoir des listes triées par ordre alphabétique pour join, j'y ajouterais un sort:

      snmpwalk -v 2c -c public -OX xxx.xxx.xxx.xxx 1.3.6.1.2.1.17.4.3.1.1 | \
      cut -c29- | \
      awk -F " " '{ print $1,$4":"$5":"$6":"$7":"$8":"$9 }' | \
      sort > /scriptsOID/mac1016.dat
      
      

      En faisant la même chose pour les fichiers bridge.dat et port.dat, les jointures peuvent se simplifier en:

      #jointure de mac1016.dat et port bridge.dat pour former mac16bridge.dat
      join -1 1 -2 1 mac1016.dat bridge.dat | \
      awk -F " " '{ if ($3<49) print $3, $2} ' | \
      sort > mac.sort
      
      #jointure de portid.dat et port.dat pour former portname.dat
      join -1 1 -2 1 portid.dat port.dat | \
      cut -d ' ' -f 2,3 | \
      awk -F " " '{ if ($1<49) print $1, $2} ' | \
      sort > ./portname.sort
      
      #jointure de mac16bridge.dat et portname.dat pour former le fichier final BD.dat
      join -1 1 -2 1 ./mac.sort portname.sort > BD.dat
      
      
      • [^] # Re: Bon autant vous montrez le complet ça vous aidera peut etre

        Posté par . Évalué à 1.

        Merci beaucoup pour ces simplifications j'avoue que c'est beaucoup plus lisible.

        je vais tester quelque truc que j'ai trouvé en fin de journée hier et je vous donnerai l'avancement .

        Merci pour tout ce temps que vous me consacré.

        • [^] # Re: Bon autant vous montrez le complet ça vous aidera peut etre

          Posté par . Évalué à 1.

          #!/bin/bash
          ########################################################################
          ########################################################################
          
          #Recuperation des addresse mac dans un fichier au format decimal et hexa
          #creation du fichier mac1016.dat contenant la relation mac hex / mac deci
          snmpwalk -v 2c -c public -OX  xxx.xxx.xxx.xxx 1.3.6.1.2.1.17.4.3.1.1 | \
          cut -c29- | \
          awk -F " " '{ print $1,$4":"$5":"$6":"$7":"$8":"$9 }' | \
          sort > /scriptsOID/mac1016.dat
          
          #recuperation du portbridge et creation de bridge.dat
          snmpwalk -v 2c  -c public -Of  xxx.xxx.xxx.xxx .1.3.6.1.2.1.17.4.3.1.2 |\
          cut  -c44- | \
          awk -F " " '{ print $1,$4 }' | \
          sort > /scriptsOID/bridge.dat
          
          #recuperation du portID et créion du fichier portid.dat
          snmpwalk -v 2c  -c public -Of  xxx.xxx.xxx.xxx .1.3.6.1.2.1.17.1.4.1.2 | \
          cut  -c45- | \
          awk -F " " '{ print $4,$1 }' | \
          sort > /scriptsOID/portid.dat
          
          #recuperation du port et créion de port.dat
          snmpwalk -v 2c  -c public -Of  xxx.xxx.xxx.xxx .1.3.6.1.2.1.31.1.1.1.1 | \
          cut -c78- | \
          awk -F " " '{ print $1,$4 }' > /scriptsOID/port.dat
          
          #jointure entre les fichier .dat pour former un fichier unique servant de base de donnee
                  #jointure de mac1016.dat et port bridge.dat pour former ma .sortc
                  join -1 1 -2 1 ./mac1016.dat <(fgrep -f <(cut -d ' ' -f 1 ./mac1016.dat) bridge.dat) | \
                  awk -F " " '{ if ($3<49) print $3, $2} ' | \
                  sort > mac.sort
          
                  #jointure de portid.dat et port.dat pour former portname.sort
                  join -1 1 -2 1 ./portid.dat <(fgrep -f <(cut -d ' ' -f 1 ./portid.dat) port.dat) | \
                  cut -d ' ' -f 2,3 | \
                  awk -F " " '{ if ($1<49) print $1, $2} ' >./portname.sort
          
                  #jointure de mac16bridge.dat et portname.dat pour former le fichier final BD.dat
                  join -1 1 -2 1 ./mac.sort <(fgrep -f <(cut -d ' ' -f 1 ./mac.sort) portname.sort)> BD.dat
          
          

          Ma dernière jointure est toujours impossible , je cherche activement une solution.

          Voici le contenu des 2 fichiers a jointer au cas ou vous auriez une idée.

          mac.sort
          1 00:B0:D0:22:46:16
          2 00:25:B3:0E:64:FE
          26 00:03:BA:12:53:6A
          27 00:03:BA:44:91:58
          28 08:00:20:CE:DB:06
          40 00:60:08:2D:27:28
          
          

          et le deuxieme :

          portname.sort
          1 Ethernet1/0/1
          2 Ethernet1/0/2
          3 Ethernet1/0/3
          4 Ethernet1/0/4
          5 Ethernet1/0/5
          6 Ethernet1/0/6
          7 Ethernet1/0/7
          8 Ethernet1/0/8
          9 Ethernet1/0/9
          10 Ethernet1/0/10
          11 Ethernet1/0/11
          12 Ethernet1/0/12
          13 Ethernet1/0/13
          14 Ethernet1/0/14
          15 Ethernet1/0/15
          16 Ethernet1/0/16
          17 Ethernet1/0/17
          18 Ethernet1/0/18
          19 Ethernet1/0/19
          20 Ethernet1/0/20
          21 Ethernet1/0/21
          22 Ethernet1/0/22
          23 Ethernet1/0/23
          24 Ethernet1/0/24
          25 Ethernet1/0/25
          26 Ethernet1/0/26
          27 Ethernet1/0/27
          28 Ethernet1/0/28
          29 Ethernet1/0/29
          30 Ethernet1/0/30
          31 Ethernet1/0/31
          32 Ethernet1/0/32
          33 Ethernet1/0/33
          34 Ethernet1/0/34
          35 Ethernet1/0/35
          36 Ethernet1/0/36
          37 Ethernet1/0/37
          38 Ethernet1/0/38
          39 Ethernet1/0/39
          40 Ethernet1/0/40
          41 Ethernet1/0/41
          42 Ethernet1/0/42
          43 Ethernet1/0/43
          44 Ethernet1/0/44
          45 Ethernet1/0/45
          46 Ethernet1/0/46
          
          

          Merci d'avance

          • [^] # Re: Bon autant vous montrez le complet ça vous aidera peut etre

            Posté par . Évalué à 0.

            join -1 1 -2 1 mac.sort <(fgrep -w -f <(cut -d ' ' -f 1 portname.sort) mac.sort)
            1 00:B0:D0:22:46:16 00:B0:D0:22:46:16
            2 00:25:B3:0E:64:FE 00:25:B3:0E:64:FE
            26 00:03:BA:12:53:6A 00:03:BA:12:53:6A
            27 00:03:BA:44:91:58 00:03:BA:44:91:58
            28 08:00:20:CE:DB:06 08:00:20:CE:DB:06
            40 00:60:08:2D:27:28 00:60:08:2D:27:28
            
            

            Voilà !

            • [^] # ça marche

              Posté par . Évalué à 1.

              vous êtes vraiment énorme , votre aide est précieuse et me redonne envie de me mettre sérieusement au bash.

              ça doit vous semblez anodin mais j'ai beaucoup appris je vous remercie.

              Je vais maintenant essayer de dynamiser encore plus le scripts en faisant appelle a un fichier contenant toute les adresse de switch .

              merci encore une grosse partie recherche et réflexion m'attend je reviendrai vers vous en cas de problème.

              cordialement benofdark.

          • [^] # Re: Bon autant vous montrez le complet ça vous aidera peut etre

            Posté par . Évalué à 3.

            Il y avait une erreur dans mon message précédent: les fichiers doivent être triés par ordre alphabétique mais uniquement sur le champ utilisé pour la jointure. Pour être sûr que le tri se fait uniquement sur ce champ et non sur toute la ligne, il faut utiliser l'option -k de sort.

            Il y a une erreur dans ton script: portname.sort n'est pas trié alphabétiquement contrairement à ce que son nom laisse supposer; port.dat non plus.

            De plus, lorsque les fichiers sont correctement triés, il est inutile de bidouiller avec des cut/fgrep pour la jointure.

            Enfin, il est inutile d'utiliser ./ devant le nom d'un fichier. Un nom de fichier qui n'est pas précédé d'un chemin est forcément dans le répertoire courant.

            #!/bin/bash
            ########################################################################
            ########################################################################
            
            #Recuperation des addresse mac dans un fichier au format decimal et hexa
            #creation du fichier mac1016.dat contenant la relation mac hex / mac deci
            snmpwalk -v 2c -c public -OX  xxx.xxx.xxx.xxx 1.3.6.1.2.1.17.4.3.1.1 | \
            cut -c29- | \
            awk -F " " '{ print $1,$4":"$5":"$6":"$7":"$8":"$9 }' | \
            sort -k 1,1 > /scriptsOID/mac1016.dat
            
            #recuperation du portbridge et creation de bridge.dat
            snmpwalk -v 2c  -c public -Of  xxx.xxx.xxx.xxx .1.3.6.1.2.1.17.4.3.1.2 |\
            cut  -c44- | \
            awk -F " " '{ print $1,$4 }' | \
            sort -k 1,1 > /scriptsOID/bridge.dat
            
            #recuperation du portID et creation du fichier portid.dat
            snmpwalk -v 2c  -c public -Of  xxx.xxx.xxx.xxx .1.3.6.1.2.1.17.1.4.1.2 | \
            cut  -c45- | \
            awk -F " " '{ print $4,$1 }' | \
            sort -k 1,1 > /scriptsOID/portid.dat
            
            #recuperation du port et creation de port.dat
            snmpwalk -v 2c  -c public -Of  xxx.xxx.xxx.xxx .1.3.6.1.2.1.31.1.1.1.1 | \
            cut -c78- | \
            awk -F " " '{ print $1,$4 }' | \
            sort -k 1,1 > /scriptsOID/port.dat
            
            #jointure entre les fichier .dat pour former un fichier unique servant de base de donnee
            #jointure de mac1016.dat et port bridge.dat pour former mac16bridge.dat
            join -1 1 -2 1 mac1016.dat bridge.dat | \
            awk -F " " '{ if ($3<49) print $3, $2} ' | \
            sort -k 1,1 > mac.sort
            
            #jointure de portid.dat et port.dat pour former portname.dat
            join -1 1 -2 1 portid.dat port.dat | \
            cut -d ' ' -f 2,3 | \
            awk -F " " '{ if ($1<49) print $1, $2} ' | \
            sort -k 1,1 > portname.sort
            
            #jointure de mac16bridge.dat et portname.dat pour former le fichier final BD.dat
            join -1 1 -2 1 mac.sort portname.sort > BD.dat
            
            

            Avec tes fichiers portname.sort et mac.sort correctement triés:

            $ cat portname.sort 
            1 Ethernet1/0/1
            10 Ethernet1/0/10
            11 Ethernet1/0/11
            12 Ethernet1/0/12
            13 Ethernet1/0/13
            14 Ethernet1/0/14
            15 Ethernet1/0/15
            16 Ethernet1/0/16
            17 Ethernet1/0/17
            18 Ethernet1/0/18
            19 Ethernet1/0/19
            2 Ethernet1/0/2
            20 Ethernet1/0/20
            21 Ethernet1/0/21
            22 Ethernet1/0/22
            23 Ethernet1/0/23
            24 Ethernet1/0/24
            25 Ethernet1/0/25
            26 Ethernet1/0/26
            27 Ethernet1/0/27
            28 Ethernet1/0/28
            29 Ethernet1/0/29
            3 Ethernet1/0/3
            30 Ethernet1/0/30
            31 Ethernet1/0/31
            32 Ethernet1/0/32
            33 Ethernet1/0/33
            34 Ethernet1/0/34
            35 Ethernet1/0/35
            36 Ethernet1/0/36
            37 Ethernet1/0/37
            38 Ethernet1/0/38
            39 Ethernet1/0/39
            4 Ethernet1/0/4
            40 Ethernet1/0/40
            41 Ethernet1/0/41
            42 Ethernet1/0/42
            43 Ethernet1/0/43
            44 Ethernet1/0/44
            45 Ethernet1/0/45
            46 Ethernet1/0/46
            5 Ethernet1/0/5
            6 Ethernet1/0/6
            7 Ethernet1/0/7
            8 Ethernet1/0/8
            9 Ethernet1/0/9
            
            $ cat mac.sort 
            1 00:B0:D0:22:46:16
            2 00:25:B3:0E:64:FE
            26 00:03:BA:12:53:6A
            27 00:03:BA:44:91:58
            28 08:00:20:CE:DB:06
            40 00:60:08:2D:27:28
            
            $ join -1 1 -2 1 mac.sort portname.sort 
            1 00:B0:D0:22:46:16 Ethernet1/0/1
            2 00:25:B3:0E:64:FE Ethernet1/0/2
            26 00:03:BA:12:53:6A Ethernet1/0/26
            27 00:03:BA:44:91:58 Ethernet1/0/27
            28 08:00:20:CE:DB:06 Ethernet1/0/28
            40 00:60:08:2D:27:28 Ethernet1/0/40
            
            
      • [^] # Re: Bon autant vous montrez le complet ça vous aidera peut etre

        Posté par . Évalué à 0.

        Une autre question qui me passé par la tête.
        Et-il possible d'effectuer un contrôle de saisie basée sur un format (exemple MAC ou IPv4)?

      • [^] # Re: Bon autant vous montrez le complet ça vous aidera peut etre

        Posté par . Évalué à 0.

        Une nouvelle question sur le même exemple de script, je me demandé si dans le fichier résulté il était possible de supprimer les ligne ayant un champ commun (exemple adresse mac) en respectant leur ordre d'arrivé dans le fichier.

    • [^] # Re: Bon autant vous montrez le complet ça vous aidera peut etre

      Posté par . Évalué à 0.

      Une nouvelle question sur le même exemple de script, je me demandé si dans le fichier résulté il était possible de supprimer les ligne ayant un champ commun (exemple adresse mac) en respectant leur ordre d'arrivé dans le fichier.

      • [^] # Re: Bon autant vous montrez le complet ça vous aidera peut etre

        Posté par . Évalué à 0.

        Oui avec la commande uniq : ça garde l. J'ai un peu adapté le fichier mac.sort pour l'exemple.

        % cat mac.sort 
        1 00:B0:D0:22:46:16
        2 00:25:B3:0E:64:FE
        12 00:03:BA:12:53:6A
        26 00:03:BA:12:53:6A
        27 00:03:BA:44:91:58
        25 00:60:08:2D:27:28
        28 08:00:20:CE:DB:06
        34 00:60:08:2D:27:28
        40 00:60:08:2D:27:28
        
        % uniq --skip-fields=1 mac.sort
        1 00:B0:D0:22:46:16
        2 00:25:B3:0E:64:FE
        12 00:03:BA:12:53:6A
        27 00:03:BA:44:91:58
        25 00:60:08:2D:27:28
        28 08:00:20:CE:DB:06
        34 00:60:08:2D:27:28
        
        

        --skip-fields (ou -f) permet d'ignorer le premier champ. Il faut alors que le reste soit identique pour que uniq puisse fonctionner. Si dans le fichier de résultat il y a des adresses mac identiques mais avec des descriptifs différents, il faut combiner plusieurs commandes

        Prenons le fichier suivant

        % cat result
        1 00:B0:D0:22:46:16 Ethernet1/0/1
        2 00:25:B3:0E:64:FE Ethernet1/0/2
        5 00:25:B3:0E:64:FE Ethernet1/0/5
        26 00:03:BA:12:53:6A Ethernet1/0/26
        27 00:03:BA:44:91:58 Ethernet1/0/27
        28 08:00:20:CE:DB:06 Ethernet1/0/28
        30 08:00:20:CE:DB:06 Ethernet1/0/29
        32 00:25:B3:0E:64:FE Ethernet1/0/32
        40 00:60:08:2D:27:28 Ethernet1/0/40
        
        

        On sélectionne les deux premiers champs, on lance le uniq et on s'en sert pour retrouver la ligne complète avec fgrep

        % grep -f <(cut -f1,2 -d\  result | uniq -f1) result
        1 00:B0:D0:22:46:16 Ethernet1/0/1
        2 00:25:B3:0E:64:FE Ethernet1/0/2
        26 00:03:BA:12:53:6A Ethernet1/0/26
        27 00:03:BA:44:91:58 Ethernet1/0/27
        28 08:00:20:CE:DB:06 Ethernet1/0/28
        32 00:25:B3:0E:64:FE Ethernet1/0/32
        40 00:60:08:2D:27:28 Ethernet1/0/40
        
        

        Seule la première occurrence est conservée

        • [^] # Re: Bon autant vous montrez le complet ça vous aidera peut etre

          Posté par . Évalué à 0.

          le problème vient justement du fait que seul la dernière occurrence (j'aurai du l'annoncer plus haut ). Si le script est lancé de maniéré régulière pour garder l'information à jour en vue d'un réseau mouvent, je doit être en mesure de gardé pour 2 MAC identique la dernière occurrence remonté.

          • [^] # Re: Bon autant vous montrez le complet ça vous aidera peut etre

            Posté par . Évalué à 0.

            Le réel problème vient de là et j'y travail . aoprès deux precolte le fichier BD.dat m'affiche

            ID MAC              Port          Switch      IP             Date      Heure
            1 00:B0:D0:22:46:16 Ethernet1/0/1 3com5500(IP= xxx.xxx.x.xx) 22-01-13 15:55:02
            1 00:B0:D0:22:46:16 Ethernet1/0/1 3com5500(IP= xxx.xxx.x.xx) 22-01-13 15:59:55
            14 00:08:02:11:D6:01 Ethernet1/0/14 3com5500(IP= xxx.xxx.x.xx) 22-01-13 15:55:02
            14 00:08:02:11:D6:01 Ethernet1/0/14 3com5500(IP= xxx.xxx.x.xx) 22-01-13 15:59:55
            15 00:04:75:FE:0E:69 Ethernet1/0/15 3com5500(IP= xxx.xxx.x.xx) 22-01-13 15:59:55
            16 00:04:75:D1:1F:69 Ethernet1/0/16 3com5500(IP= xxx.xxx.x.xx) 22-01-13 15:55:02
            16 00:04:75:D1:1F:69 Ethernet1/0/16 3com5500(IP= xxx.xxx.x.xx) 22-01-13 15:59:55
            18 00:90:05:00:86:61 Ethernet1/0/18 3com5500(IP= xxx.xxx.x.xx) 22-01-13 15:55:02
            18 00:90:05:00:86:61 Ethernet1/0/18 3com5500(IP= xxx.xxx.x.xx) 22-01-13 15:59:55
            19 00:21:5A:BD:F4:7C Ethernet1/0/19 3com5500(IP= xxx.xxx.x.xx) 22-01-13 15:55:02
            19 00:21:5A:BD:F4:7C Ethernet1/0/19 3com5500(IP= xxx.xxx.x.xx) 22-01-13 15:59:55
            20 00:13:20:63:18:15 Ethernet1/0/20 3com5500(IP= xxx.xxx.x.xx) 22-01-13 15:55:02
            20 00:13:20:63:18:15 Ethernet1/0/20 3com5500(IP= xxx.xxx.x.xx) 22-01-13 15:59:55
            21 00:19:B9:3E:0A:26 Ethernet1/0/21 3com5500(IP= xxx.xxx.x.xx) 22-01-13 15:55:02
            21 00:19:B9:3E:0A:26 Ethernet1/0/21 3com5500(IP= xxx.xxx.x.xx) 22-01-13 15:59:55
            
            

            Il faut que j'arrive a géré les doublons sur le 3eme champ en gardant le plus vieux

            • [^] # Re: Bon autant vous montrez le complet ça vous aidera peut etre

              Posté par . Évalué à 0.

              erreur de ma part c'est sur le 2 eme champs.

              • [^] # Re: Bon autant vous montrez le complet ça vous aidera peut etre

                Posté par . Évalué à 0.

                tac (cat à l'envers) permet d'afficher les lignes dans l'ordre inverse, ça me permet de contourner le fait que uniq garde la première ligne

                Avec deux tac et un peu de awk au lieu de uniq, on peut supprimer les doublons.

                % tac BD.dat | awk 'BEGIN { r="" } { while ($3 == r) { next } ; r = $3 ; print }' | tac
                ID MAC              Port          Switch      IP             Date      Heure
                1 00:B0:D0:22:46:16 Ethernet1/0/1 3com5500(IP= xxx.xxx.x.xx) 22-01-13 15:59:55
                14 00:08:02:11:D6:01 Ethernet1/0/14 3com5500(IP= xxx.xxx.x.xx) 22-01-13 15:59:55
                15 00:04:75:FE:0E:69 Ethernet1/0/15 3com5500(IP= xxx.xxx.x.xx) 22-01-13 15:59:55
                16 00:04:75:D1:1F:69 Ethernet1/0/16 3com5500(IP= xxx.xxx.x.xx) 22-01-13 15:59:55
                18 00:90:05:00:86:61 Ethernet1/0/18 3com5500(IP= xxx.xxx.x.xx) 22-01-13 15:59:55
                19 00:21:5A:BD:F4:7C Ethernet1/0/19 3com5500(IP= xxx.xxx.x.xx) 22-01-13 15:59:55
                20 00:13:20:63:18:15 Ethernet1/0/20 3com5500(IP= xxx.xxx.x.xx) 22-01-13 15:59:55
                21 00:19:B9:3E:0A:26 Ethernet1/0/21 3com5500(IP= xxx.xxx.x.xx) 22-01-13 15:59:55
                
                

                Il y a peut-être une solution plus élégante et si quelqu'un est motivé, ça m'intéresse de la connaître.

                • [^] # Re: Bon autant vous montrez le complet ça vous aidera peut etre

                  Posté par . Évalué à 1.

                  La commande "uniq" a aussi une option "-w" ;-)))

                  tac data | uniq -f 1 -w 17 | tac
                  
                  
                • [^] # Re: Bon autant vous montrez le complet ça vous aidera peut etre

                  Posté par . Évalué à 1.

                  Juste pour m'aider à apprendre awk, voici une solution sans tac

                  % awk '
                  BEGIN {
                          getline previousline
                  }
                  {
                          if ($3 != previousfield) {
                                  print previousline
                          }
                          previousfield = $3
                          previousline = $0
                  }
                  END {
                          print previousline
                  }' BD.dat
                  ID MAC              Port          Switch      IP             Date      Heure
                  1 00:B0:D0:22:46:16 Ethernet1/0/1 3com5500(IP= xxx.xxx.x.xx) 22-01-13 15:59:55
                  14 00:08:02:11:D6:01 Ethernet1/0/14 3com5500(IP= xxx.xxx.x.xx) 22-01-13 15:59:55
                  15 00:04:75:FE:0E:69 Ethernet1/0/15 3com5500(IP= xxx.xxx.x.xx) 22-01-13 15:59:55
                  16 00:04:75:D1:1F:69 Ethernet1/0/16 3com5500(IP= xxx.xxx.x.xx) 22-01-13 15:59:55
                  18 00:90:05:00:86:61 Ethernet1/0/18 3com5500(IP= xxx.xxx.x.xx) 22-01-13 15:59:55
                  19 00:21:5A:BD:F4:7C Ethernet1/0/19 3com5500(IP= xxx.xxx.x.xx) 22-01-13 15:59:55
                  20 00:13:20:63:18:15 Ethernet1/0/20 3com5500(IP= xxx.xxx.x.xx) 22-01-13 15:59:55
                  21 00:19:B9:3E:0A:26 Ethernet1/0/21 3com5500(IP= xxx.xxx.x.xx) 22-01-13 15:59:55
                  
                  

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.