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

Langage Perl Discussion :

Comment ne récupérér que telle ou telle colonne d'un tableau


Sujet :

Langage Perl

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Janvier 2010
    Messages
    84
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 84
    Par défaut Comment ne récupérér que telle ou telle colonne d'un tableau
    bonjour,

    J'ai commencé perl que trés récément et en "autoformation". Ce qui fait que parfois je bloque....
    et là je ne sais plus comment faire!

    Je cherche à faire un tri sur un fichier txt qui se présente sous la forme suivante:

    Tue 1/12/10 07:34:13: , 127.0.0.1, 29, 0,1, toto, tata, , titi1
    Tue 1/12/10 07:34:13: , 127.0.0.1, 29, 0,1, toto, tata, , titi2
    Tue 1/12/10 11:34:13: , 127.0.0.1, 31, 0,1, toto, tata, , titi3
    Tue 1/12/10 08:34:13: , 127.0.0.1, 29, 0,1, toto, tata, , titi1
    Tue 1/12/10 14:34:13: , 127.0.0.1, 29, 0,1, toto, tata, , titi4
    ...... avec bien sur des milliers de lignes.

    le but final de mon script est de compter le nombre de titi distinct heure par heure!

    Mon problème initial est que je ne sais pas comment récupérer que telle ou telle colonne de ce fichier txt (qui pour la petite histoire est l'accumulation de 4 autres fichiers!!).
    En effet, si je considère les espaces comme séparateur, seules la colonne 1, 2, 3 et la dernière m'intérressent.

    Initiallement, dans ma première version du script, je ne prenais pas en compte cette variable du temps. Par conséquent, il me suffisait de garder le dernier champs.
    Pour cela, je passais par:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    	open(FILE,"<$file") or die ("Impossible to open the file $file.\n");
    	while( my $line = <FILE> ) {
    		#retrive the last field of each line
    		my $last_field = (split m/\s+/, $line)[-1];
    		#store in the list of result, only the fields whith the length between 2 and 20 digits
    		if ((length($last_field) < 2) || (length($last_field) > 20)) {
    		}
    		else {
    		push (@complete_users_list, $last_field);
    		}
    	}
    	close FILE;
    mais afin de pouvoir faire un tri ultérieurement sur les dates, colonnes 1, 2 et 3 (pour un futur split heure/heure --> va pas être simple non plus), il me faut garder plusieurs champs et là je bloque!!

    Par avance merci pour votre aide

    Yzf-r

  2. #2
    Membre éprouvé
    Avatar de Jasmine80
    Femme Profil pro
    Bioinformaticienne
    Inscrit en
    Octobre 2006
    Messages
    3 157
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 45
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Bioinformaticienne
    Secteur : Santé

    Informations forums :
    Inscription : Octobre 2006
    Messages : 3 157
    Par défaut
    Tu peux récupérer plusieurs champs via le split, ça ressemblerait à quelque chose de ce genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my ($time_field, $last_field) = (split m/\s+/, $line)[1, -1];
    Ensuite pour compter le nombre de titi distincts heure par heure, tu peux utiliser un hash

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    my %titi_count;
     
    $titi_count{$time} ++;
    Et si tu veux garder les listes précises des titi par heure, tu fais un hash de array (donc tu associes à chaque clé du hash un array).

  3. #3
    Membre confirmé
    Inscrit en
    Janvier 2010
    Messages
    84
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 84
    Par défaut
    Merqui Jasmine80,

    J'ai tenté le coup comme ci-dessous suite à ta réponse:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    my @non_sorted_list =();
    #Keep only the fields #1, #2, #3 and the last one
    open(TEMP,"<$temp_access") or die ("Impossible to open the file $temp_access.\n");
    while( my $line_temp = <TEMP> ) {
    	#retrieve the last field of each line
    	#my $last_field = (split m/\s+/, $line_temp)[-1];
    	my ($time_field, $last_field) = (split m/\s+/, $line)[1, -1];
    	#push (@non_sorted_list, $last_field);
    	push (@non_sorted_list, $time_field, $last_field);
    }
    close TEMP;
    mais il crashe: Use of uninitialized value in split at KPI_V3.pl line 193, <TEMP> line 25165.
    ....

    j'ai tenté en parrallèle de la manière suivante:
    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
     
    my @non_sorted_list =();
    #Keep only the fields #1, #2, #3 and the last one
    open(TEMP,"<$temp_access") or die ("Impossible to open the file $temp_access.\n");
    while( my $line_temp = <TEMP> ) { 
    	my $last_field = (split m/\s+/, $line_temp)[-1];
    	my $time_field = (split m/\s+/, $line_temp)[0];
    	push (@non_sorted_list, $time_field, $last_field);
    }
    close TEMP;
     
    open (FH, ">test-sort.txt");
    foreach $each (@non_sorted_list) {
    print FH $each."\n";
    }
    mais cette fois, lorsque je le sors dans un fichier txt, le format n'est pas bon.
    J'ai:

    Tue
    titi1
    Tue
    titi2
    ...

    Alors que je voudrais (parce que je pense que c'est nécessaire pour le tri ensuite, j'ai peut-être tort?):
    Tue titi1
    Tue titi2
    ...

    Yzf-r

  4. #4
    Membre éprouvé
    Avatar de Jasmine80
    Femme Profil pro
    Bioinformaticienne
    Inscrit en
    Octobre 2006
    Messages
    3 157
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 45
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Bioinformaticienne
    Secteur : Santé

    Informations forums :
    Inscription : Octobre 2006
    Messages : 3 157
    Par défaut
    Citation Envoyé par yzf-r Voir le message

    J'ai tenté le coup comme ci-dessous suite à ta réponse:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    my @non_sorted_list =();
    #Keep only the fields #1, #2, #3 and the last one
    open(TEMP,"<$temp_access") or die ("Impossible to open the file $temp_access.\n");
    while( my $line_temp = <TEMP> ) {
    	#retrieve the last field of each line
    	#my $last_field = (split m/\s+/, $line_temp)[-1];
    	my ($time_field, $last_field) = (split m/\s+/, $line)[1, -1];
    	#push (@non_sorted_list, $last_field);
    	push (@non_sorted_list, $time_field, $last_field);
    }
    close TEMP;
    mais il crashe: Use of uninitialized value in split at KPI_V3.pl line 193, <TEMP> line 25165.
    ....
    C'est normal tu déclares la variable $line_temp puis tu utilises $line dans le split

    Citation Envoyé par yzf-r Voir le message
    j'ai tenté en parrallèle de la manière suivante:
    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
     
    my @non_sorted_list =();
    #Keep only the fields #1, #2, #3 and the last one
    open(TEMP,"<$temp_access") or die ("Impossible to open the file $temp_access.\n");
    while( my $line_temp = <TEMP> ) { 
    	my $last_field = (split m/\s+/, $line_temp)[-1];
    	my $time_field = (split m/\s+/, $line_temp)[0];
    	push (@non_sorted_list, $time_field, $last_field);
    }
    close TEMP;
     
    open (FH, ">test-sort.txt");
    foreach $each (@non_sorted_list) {
    print FH $each."\n";
    }
    mais cette fois, lorsque je le sors dans un fichier txt, le format n'est pas bon.
    J'ai:

    Tue
    titi1
    Tue
    titi2
    ...

    Alors que je voudrais (parce que je pense que c'est nécessaire pour le tri ensuite, j'ai peut-être tort?):
    Tue titi1
    Tue titi2
    ...

    Yzf-r
    Tu utilises un array, donc tous tes éléments sont stockés l'un à la suite de l'autre dans l'ordre initial (selon le push).

    Ne peux-tu pas écrire dans le fichier de sortie au fur et à mesure que tu récupères les données dans le fichier d'entrée?
    Tes titi sont-ils uniques?
    Veux-tu garder l'ordre initial du fichier d'entrée dans le fichier de sortie?

  5. #5
    Membre confirmé
    Inscrit en
    Janvier 2010
    Messages
    84
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 84
    Par défaut
    effectivement erreur de débutant

    Ma première version du script est celle-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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
     
     
    #Retrieve all files from the given folder: ARG[0] --> the argument 1 
    my $access_log_folder = $ARGV[0];
    #Criteria to filter the files names: ARG[1] --> the argument 2
    my $log_name = $ARGV[1];
    my @files = ();
    opendir (my $rep_fh, $access_log_folder) or die "impossible to open the folder $access_log_folder.\n";
    my @file_rep = grep { !/^\.\.?$/ } readdir($rep_fh); 
    closedir ($rep_fh);
     
    #Keep only the files starting with the given criteria
    @Acces_only = grep(/^$log_name/, @file_rep); 
     
    foreach my $name (@Acces_only) {
    	if ( -f "$access_log_folder/$name" ) {
    		push (@files, "$access_log_folder/$name" ); 
    	}
    }
     
    print "The access.log files found are:\n";
    foreach my $file (@files){
    	print $file." \n";
    }
     
    #number of files to be treated
    my $how_many_files = $#files+1;
    print "==> The number of files to be treated is $how_many_files.\n";
    print " \n";
     
    #exit if no file to be treated
    print "There is no file to be treated. KPI Stopped!\n" and exit unless ($how_many_files > 0);
     
    my @complete_users_list = ();
    my $i = 0;
    foreach $file (@files){
    	$i = $i + 1;
    	open(FILE,"<$file") or die ("Impossible to open the file $file.\n");
    	while( my $line = <FILE> ) {
    		#retrive the last field of each line
    		my $last_field = (split m/\s+/, $line)[-1];
    		#store in the list of result, only the fields whith the length between 2 and 20 digits, corresponding to a user login
    		if ((length($last_field) < 2) || (length($last_field) > 20)) {
    		}
    		else {
    		push (@complete_users_list, $last_field);
    		}
    	}
    	close FILE;
    	print "The file $i has been successfully treated!\n";
    }
     
    #define the list of distinct users login
    my @uniq = ();
    %seen = ();
    foreach $item (@complete_users_list) {
        push(@uniq, $item) unless $seen{$item}++;
    }
    Maintenant, je veux prendre en compte la variable temps et faire des découpages heures par heures pour voir la montée en charge.

    Comme tu peux le voir ci-dessous, je dois traiter plusieurs fichiers.

    Donc j'étais parti sur une première étape qui était de grouper tous les fichiers en un seul, le trier, le découper et faire le même "uniq" traitement ensuite pour déterminer les différents titi.

    et là, ça coince

    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
     
    #Merge all files in one temporary file
    open (TEMP, ">Temp_access.log");
    close TEMP;
    my $temp_access = "Temp_access.log";
     
    foreach $file (@files){
    	open(TEMP, ">>$temp_access") or die ("Impossible to open the temporary file $temp_access.\n");
    	open(FILE,"<$file") or die ("Impossible to open the file $file.\n");
    	while (<FILE>){
    	print TEMP $_;}
    	close FILE;
    	close TEMP;
    }
     
    my @non_sorted_list =();
    #Keep only the fields #1, #2, #3 and the last one
    open(TEMP,"<$temp_access") or die ("Impossible to open the file $temp_access.\n");
    while( my $line_temp = <TEMP> ) {
    	#retrieve the last field of each linerm 
    	#my $last_field = (split m/\s+/, $line_temp)[-1];
    	my ($time_field, $last_field) = (split m/\s+/, $line_temp)[1, -1];
    	#push (@non_sorted_list, $last_field);
    	push (@non_sorted_list, $time_field, $last_field);
    }
    close TEMP;
    C'est pour cela qu'à la suite du premier tri (champs 1, 2, 3 et dernier), garder l'ordre n'est pas impératif.

  6. #6
    Membre éprouvé
    Avatar de Jasmine80
    Femme Profil pro
    Bioinformaticienne
    Inscrit en
    Octobre 2006
    Messages
    3 157
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 45
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Bioinformaticienne
    Secteur : Santé

    Informations forums :
    Inscription : Octobre 2006
    Messages : 3 157
    Par défaut
    et quelque chose de ce genre :
    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
    #Merge all files in one temporary file
    open (TEMP, ">Temp_access.log");
    close TEMP;
    my $temp_access = "Temp_access.log";
     
    foreach $file (@files){
    	open(TEMP, ">>$temp_access") or die ("Impossible to open the temporary file $temp_access.\n");
    	open(FILE,"<$file") or die ("Impossible to open the file $file.\n");
    	while (<FILE>){
    	print TEMP $_;}
    	close FILE;
    	close TEMP;
    }
     
    my %non_sorted_list;
    #Keep only the fields #1, #2, #3 and the last one
    open(TEMP,"<$temp_access") or die ("Impossible to open the file $temp_access.\n");
    while( my $line_temp = <TEMP> ) {
    	#retrieve the last field of each linerm 
    	#my $last_field = (split m/\s+/, $line_temp)[-1];
    	my ($time_field, $last_field) = (split m/\s+/, $line_temp)[1, -1];
    	#push (@non_sorted_list, $last_field);
    	push (@{$non_sorted_list{$time_field}}, $last_field);
    }
    close TEMP;
     
    foreach my $time (sort keys %non_sorted_list){
    	map {print "$time\t$_\n";} @{$non_sorted_list{$time}};
    }

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

Discussions similaires

  1. Réponses: 10
    Dernier message: 22/12/2014, 19h58
  2. [CSS 3] Comment faire pour que ma colonne central s'adapte
    Par pierrot10 dans le forum Mise en page CSS
    Réponses: 12
    Dernier message: 19/04/2011, 14h23
  3. [XL-2000] (InputBox) comment lui faire comprendre que la valeur "G" = colonne G ?
    Par wyzer dans le forum Macros et VBA Excel
    Réponses: 8
    Dernier message: 11/06/2010, 17h05
  4. Réponses: 2
    Dernier message: 30/03/2009, 14h13
  5. Réponses: 6
    Dernier message: 16/01/2007, 22h34

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