Awk-perl

Résolu
Bonjour,
j'ai un fichier hexadécimal le séparateur de chaque mot hexa et "|"
je voulais extraire des mots specifiques

en fait, c'est fichier tres long qui ressemble a celui de Wireshark l'or d'un enregistrement *.txt

je voulais tester $44

cat /home/../Bureau/hexa.txt | awk -F| `BEGIN {NR=4; int Nseq=0;int num=0;}
{

if( $44!="60")
{num = NR; Nseq =strcat($45,$46); NR=NR+32;}

else
{num = NR; NR=NR+33;}
}
END {print num " " Nseq}`>>/home/../Bureau/rtp.txt

ce code je veux l'introduire dans le script perl
puis-je le faire et comment ?
y a t-il des fautes dans ce bout de code svp?
merci bcp
Configuration: Windows XP
Firefox 3.0.8

75 réponses

Résumé de la discussion

Un fichier hexadécimal contenant des mots séparés par le caractère pipe présente une problématique d’extraction ciblée, nécessitant une combinaison d’outils comme awk et perl pour isoler certaines colonnes. Les tentatives utilisent awk -F| et des blocs BEGIN/END avec des compteurs NR, puis l’intégration dans un script Perl, signalant des difficultés liées au séparateur et aux sauts de ligne. Plusieurs facteurs techniques, notamment Windows CRLF et un fichier long semblable à une capture Wireshark, orientent les propositions vers l’ajustement des blocs de 32 lignes et l’adaptation du séparateur selon l’environnement.

Bobot (l’IA à votre service)
  1. j'ai un fichier d'une centaine de lignes chaque ligne comporte 49 colonnes ou mots
    j'en ai besoin seulement de la 44ieme, 45ieme et 46ieme colonne seulement de chaque bloque de 32 lignes

    est ce que perl permet un saut de ligne???
    1. Modérateur
      Re,

      Tu ne me dérange pas, mais j'avoue que je ne comprends toujours pas.

      Je vois que tu mest une condition pour la 1ère donnée (égal à 60), mais je ne comprends pas l'incrementation.
      Bref, il faut que tu me montre un exemple concret sur un fichier.

      Tu peux faire une analogie, en utilisant par exemple 3 au lieu de 32

      En ce qui concerne les séparateurs ce n'est pas difficile.
      1. Modérateur
        Re,

        Si ce n'est pas confidentiel tu peux le mettre sur cjoint.com et me donner le lien ici.
        Le cas contraire tu peux m'envoyer le lien de cjoint.com par MP

        Je vais regarder ce soir, je suis au boulot et je ne peux pas tester.
        1. a titre d'exemple ce code marche correctement sauf le separateur que j'ai est '|' (pipe)
          et les conditions de saut de ligne pas encore

          # !/usr/bin/perl -w

          use strict;
          use warnings;

          open LIRE,"/home/sst/Bureau/hexa.txt" or die "fichier in trouvable";
          open ECRIRE,">/home/sst/Bureau/rtp.txt\n", or die "E/S : $!\n";

          while(<LIRE>)
          {
          if($. % 3 == 1){
          my ($data_4, $data_5, $data_6, $data_7)= (split /\s/,$_)[4, 5, 6, 7];
          print ECRIRE "ligne$. $data_4 $data_5 $data_6 \n";
          }

          }
          1. Modérateur
            Re,

            Non, ça ne marche pas ton code.
            Ton fichier est crée sous windows il me semble.

            Le problème avec ton fichier c'est qu'il y a des lignes que tu ne traites pas.
            Donc tu ne peux pas faire un pas d'incrementation si tu ne supprimes pas d'abord ces lignes.

            Je parle de ça
            +---------+---------------+----------+
            10:29:55,459,489   ETHER
            Donc il faut sauter des lignes.

            Quand je t'ai demandé un exemple concret je parlais d'un exemple aussi de sortie.

            Tu m'as donné seulement l'entrée.
            Dans le fichier que tu as mis sur cjoint la ligne 4 ne contient rien.
            Mais le % == 4 c'est la condition correct
            Voici le résultat à partir de la ligne 7
            lami20j@debian:~$ cat karim.pl
            # !/usr/bin/perl -w
            
            use strict;
            use warnings;
            
            
            open LIRE,"hexa.txt" or die "fichier in trouvable";
            #open ECRIRE,">/home/sst/Bureau/rtp.txt\n", or die "E/S : $!\n";
            
            while(<LIRE>)
            {
            #       next unless /^\|/;
                    my @t=(split /\|/,$_)[10..13];
                    {
                      $"='|';
                      print "ligne$. @t\n" if $. % 32 == 7;
                    }
            }
            lami20j@debian:~$ perl karim.pl
            ligne7 57|00|0c|e1
            ligne39 57|00|0c|e1
            ligne71 57|00|0c|e1
            ligne103 57|00|0c|e1
            
            1. Modérateur
              Salut,

              ce code je veux l'introduire dans le script perl
              puis-je le faire et comment ?

              Pourquoi pas faire directement en Perl?!!
              1. Modérateur
                Re,

                Quand tu parles de colonnes seulement, alors ça n'a rien à avoir avec le bloc d'un nb de lignes.
                Il suffit d'extraire les colonnes.

                Tu ne veux pas plutôt certaines éléments qui se trouves à l'intersection des colonnes avec les lignes 1, 33, 65, etc. ?
                1. Modérateur
                  Re,

                  Par exemple
                  lami20j@debian:~/trash$ cat bloc.pl
                  #!/usr/bin/perl
                  use strict;use warnings;
                  
                  while(<DATA>){
                    print "ligne$. ",(split /\s/,$_)[1,3],"\n" if $. % 3 == 1;
                  }
                  __END__
                  a b c 0
                  d e f 1
                  g h i 2
                  j k l 3
                  m n o 4
                  p k r 5
                  s t u 6
                  v w x 7
                  
                  lami20j@debian:~/trash$ perl bloc.pl
                  ligne1 b0
                  ligne4 k3
                  ligne7 t6

                  1. bonjour

                    merci pour ta réponse Mr lami20j, mais j'ai un problème que je dois commencer le parsing dés la 4ieme ligne car les 4 première ligne ne comprennent pas de données utiles

                    a propos aussi, je voudrai Mr enregistrer ces données dans un fichier pour que je puisse les extraire et récuperer tout les données

                    while(<DATA>){
                    print "ligne$. ",(split /\s/,$_)[44,45,46],"\n" if $. % 32 == 1;
                    }
                    1. Modérateur
                      Salut,

                      Essaie (je n'ai pas testé)
                      Il faut que tu mettes les chemin pour le fihcier à lire et pour le fichier resultat
                      open LIRE,"cheminvers le fichier" or die "E/S : $!\n";
                      open ECRIRE,">cheminvers le fichier resultat\n", or die "E/S : $!\n";
                      
                      while(<LIRE>){ 
                        print ECRIRE "ligne$. ",(split /\s/,$_)[44,45,46],"\n" if $. % 32 == 4; 
                      }
                      1. tu m'as pas bien compris en ce qui concerne Mr Lami mais merci bien pour ta reponse

                        je veux faire le parcours de mon fichier dés la 4ieme ligne
                        autrement les 4 premiere lignes doivent etre ignorer

                        et si jamais tu me donne un astuce pour séparer les donnés sauvegarder dans le fichier destinataire par un espace ou : ou , n'importe
                        1. me m'exprime mal desolé Mr Lami20j

                          en fait
                          * je veux extraire a partir de la 4ieme ligne
                          * extraire les 44, 45 et 46 ieme colonne du ligne en cours
                          - si $44 == 60
                          ligne++;
                          extraire la colonne 6 et 7 ;
                          ligne = ligne + 32;

                          - sinon ligne =ligne +32;

                          je m'excuse si jamais je t'ai dérangé et merci bcp
                          1. j'ai remarquer un changement l'or de l'ouverture du fichier sur linux d'ou il aura qq petites changement

                            si tu veux que je t'envoi un exemple concret je peux t'envoyer le fichier "hexa.txt"

                            c'est une capture de suite de trames encapsulées
                            le fichier enregistré est en hexadecimal chaque mot séparé par un pipe "|" (wireshark capture)

                            mais en resumant je veux faire un test sur $45 . si $45=60 donc il s'agit d'une encapsulation de l'entete FEC apres l'entete RTP puis il faut que je cherche le numero de sequence du paquet dans la ligne suivante :$3 et $4 en les concatenant et les converssnat en decimal.
                            differemment si $45==21, dans ce cas le numero de sequence se trouve dans la meme ligne exactement $46 et $47, (dans ce cas on n'a pas d'encapsulation FEC)

                            car s'il s'agit du cas du FEC ($45=60) puis il me faut un saut de 28 lignes pour parcourir la trame qui suit
                            tandis que dans le cas de RTP ($45=21) il me faut un saut de 29 lignes
                            1. salut Mr

                              j'ai trouver la solution malgré qu'elle me somble bizzar . en tt cas je te remerci bcp et c'est grace a votre aide

                              # !/usr/bin/perl -w

                              use strict;
                              use warnings;

                              open LIRE,"/home/sst/Bureau/karim/capture/karimov.txt" or die "fichier in trouvable";
                              open ECRIRE,">/home/sst/Bureau/rtp.txt\n", or die "E/S : $!\n";

                              while(<LIRE>)
                              {
                              if($. % 4 == 3){
                              my ($data_135, $data_136, $data_138, $data_139, $data_141, $data_142, $data_168, $data_169, $data_171, $data_172)= (split /|/,$_)[135, 136, 138, 139, 141, 142, 168, 169, 171, 172];
                              print ECRIRE "ligne$. \t $data_135 $data_136 $data_138 $data_139 $data_141 $data_142 $data_168 $data_169 $data_171 $data_172\n";
                              }
                              }

                              si jamais je rencontre un prb Mr est ce que je peux vous contacter?
                              la tache n'est pas terminer aussi il me reste un tout petit peu
                              je vais essayer seul et si jamais je tombe en panne je te demande de m'aider et merci bcp
                              n'hesiter pas de commenter mon code
                              1. Modérateur
                                Salut,

                                si jamais je rencontre un prb Mr est ce que je peux vous contacter?
                                C'est un plaisir d'aider quelqu'un qui essaie d'abord faire tout seul.
                                Tu peux toujours poser tes questions. Que ça soit moi où une autre personne tu trouveras un coup de main ;-).

                                Je vais essayer d'améliorer un peu ton code. Tu me diras si tu obtiens le même résultat
                                Plus tard je vais essayer aussi de t'expliquer le code.
                                #!/usr/bin/perl -w
                                
                                use strict;use warnings;
                                
                                open LIRE,"/home/sst/Bureau/karim/capture/karimov.txt" or die "fichier in trouvable";
                                open ECRIRE,">/home/sst/Bureau/rtp.txt\n" or die "E/S : $!\n";
                                
                                while(<LIRE>){
                                  if($. % 4 == 3){
                                    my @data= (split /|/,$_)[135,136,138,139,141,142,168,169,171,172];
                                    print ECRIRE "ligne$. \t@data\n";
                                  }
                                }
                                Si jamais tu as besoin des variables tu peux toujours les utiliser de la facon $data[indicetableau]

                                1. Bonjour Mr

                                  le code que vous m'avez proposé ne ne fonctionne pas correctement
                                  my @data= (split /|/,$_)[135,136,138,139,141,142,168,169,171,172];
                                  print ECRIRE "ligne$. \t@data\n";
                                  le resultat dans le fichier resultat est :
                                  ligne3
                                  ligne7
                                  ligne11
                                  ligne15
                                  ligne19

                                  tandis que,

                                  my ($data_135, $data_136, $data_138, $data_139, $data_141, $data_142, $data_168, $data_169, $data_171, $data_172)= (split /|/,$_)[135, 136, 138, 139, 141, 142, 168, 169, 171, 172];
                                  print ECRIRE "ligne$. \t $data_135 $data_136 $data_138 $data_139 $data_141 $data_142 $data_168 $data_169 $data_171 $data_172\n";

                                  m'a donné hier le bon resultat mais aujourd'hui des erreur de compilations
                                  expl:
                                  Use of uninitialized value $data_171 in concatenation (.) or string at test.pl line 12, <LIRE> line 4955.
                                  j'ai pas compris pourquoi exactement
                                  1. c fait avec succés
                                    un petit truc qui manque c'est
                                    chmod +x chemin_du_fichier

                                    ce que je voudrai bien le savoir c'est comment extraire les deux premiers arguments en les concatenant puis convertir ce nombre hexa en decimal

                                    exple :

                                    ligne3 21 a515 4704
                                    ligne7 21 a516 4704
                                    ligne11 21 a517 4704
                                    ligne15 21 a518 4704
                                    ligne19 60 876c a4e4
                                    ligne23 21 a519 4704
                                    ligne27 21 a51a 4704
                                    ligne31 21 a51b 4704
                                    ligne35 60 876d a4e5
                                    ligne39 60 876e a4e6

                                    trouve = false;
                                    while (trouve ==true)
                                    je voudrai exactement analyser la deuxieme colonne
                                    si $2==60
                                    first=hex($4);
                                    chercher d'avantage la seconde apparition de '60' a la colenne 4 ($4)
                                    second = hex ($4);
                                    si (second - first==33)
                                    trouve = true;

                                    pour le moment chui entrain de programmer cette tache
                                    je veux juste un coup de main pour que je puisse continuer
                                    car comme vous le savez chui debutant en perl

                                    merci bcp
                                    1. Modérateur
                                      Salut,

                                      j'ai pas compris pourquoi exactement
                                      Si le code fonctionne dans certains cas alors il faut peut être étudier le fichiers d'entrée.

                                      Normalement mon code doit fonctionner. En fin de compte un tableau n'est qu'une liste où on peut appliquer certaines fonctions.

                                      Pour l'extraction que tu veux faire, il ne faut pas oublie que tu dois parcourir le résultat qui est un fichier.
                                      Ensuite il faut tenir compte de séparateur qui est un espace.
                                      1. j'ai eu l'idée d'analyser le nouveau fichier rtp.txt
                                        et mettre toutes les 4ieme arguments dans un tableau a condition que le deuxieme argument soit egale a 60

                                        open FILE,"/home/sst/Bureau/rtp.txt" or die "E/S : $!\n";

                                        my($line,@words,$word,%total);
                                        while( defined( $line = <FILE> ) )
                                        {
                                        @words = split( /\W+/, $line );
                                        foreach my $word (@words)
                                        {
                                        if ($word eq '60')
                                        {
                                        my @table = $words[4];
                                        }
                                        }}

                                        tojours des msg d'erreur
                                        est ce que c'est faisable ou non? car je veux comparer les SNBL ($4 4iemes champs) ensemble
                                        il faut que je trouve une difference = 33 c'est l'SNBL ($4) que je cherche
                                        • 1
                                        • 2
                                        • 3
                                        • 4