Aggreger valeurs des lignes ayant des champs

Résolu/Fermé
Decon Messages postés 91 Date d'inscription mercredi 29 août 2007 Statut Membre Dernière intervention 8 octobre 2014 - 5 mai 2012 à 10:35
Decon Messages postés 91 Date d'inscription mercredi 29 août 2007 Statut Membre Dernière intervention 8 octobre 2014 - 9 mai 2012 à 01:13
Bonjour,

Soit le fichier FIC de contenu:
P1:A:TOTO:VAL1:62
P1:A:TOTO:VAL1:56
P1:A:TOTO:VAL2:5
P1:B:TOTO:VAL2:4
P1:A:TITI:VAL1:62
P2:A:TOTO:VAL2:59
P1:B:TITI:VAL6:5
P2:A:TOTO:VAL1:9
P2:B:BLABLA:VAL4:5
P2:B:TOTO:VAL2:61
P2:B:BLABLA:VAL4:51

Je souhaite pourvoir aggréger les lignes du fichier suivant les champs 2,3 et 4. Le séparateur étant ":".

Ce qui devrait me donner le résultat suivant:
A:TOTO:VAL1:127
A:TOTO:VAL2:64
B:TOTO:VAL2:65
B:BLABLA:VAL4:56
A:TITI:VAL1:62
B:TITI:VAL6:5

Merci d'avance.

10 réponses

dubcek Messages postés 18718 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 22 mars 2024 5 615
Modifié par dubcek le 5/05/2012 à 11:06
hello
avec quel outil ? awk ?
$ awk -F':' '{x[$2, $3, $4]+=$5} END{for (n in x){i=n ; gsub(SUBSEP, FS, n) ; print n FS x[i]}}' fichierFIC  
A:TITI:VAL1:62  
B:BLABLA:VAL4:56  
B:TITI:VAL6:5  
B:TOTO:VAL2:65  
A:TOTO:VAL1:127  
A:TOTO:VAL2:64  
$  
0
Decon Messages postés 91 Date d'inscription mercredi 29 août 2007 Statut Membre Dernière intervention 8 octobre 2014 2
Modifié par Decon le 5/05/2012 à 11:38
Merci de ta réponse.

En perl. Je dois l'intégrer à un code perl que j'ai déjà implémenté.

Sinon, peux tu m'expliquer ce que fait ton script?
0
dubcek Messages postés 18718 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 22 mars 2024 5 615
5 mai 2012 à 12:16
en utilisant a2p (1) - Awk to Perl translator
#!/usr/bin/perl
eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
    if $running_under_some_shell;
			# this emulates #! processing on NIH machines.
			# (remove #! line above if indigestible)

eval '$'.$1.'$2;' while $ARGV[0] =~ /^([A-Za-z_0-9]+=)(.*)/ && shift;
			# process any FOO=bar switches

$FS = ':';		# set field separator
$, = ' ';		# set output field separator
$\ = "\n";		# set output record separator

while (<>) {
    chomp;	# strip record separator
    ($Fld1,$Fld2,$Fld3,$Fld4,$Fld5) = split($FS, $_, -1);
    $X{$Fld2, $Fld3, $Fld4} += $Fld5;
}

foreach $n (keys %X) {
    $i = $n;
    ($s_ = '"'.($FS).'"') =~ s/&/\$&/g, $n =~ s/$;/eval $s_/ge;
    print $n . $FS . $X{$i};
}

$
0
Decon Messages postés 91 Date d'inscription mercredi 29 août 2007 Statut Membre Dernière intervention 8 octobre 2014 2
5 mai 2012 à 13:38
Grand merci dubcek. C'est gentil de ta part.

Il me reste plus qu'à essayer de comprendre.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Decon Messages postés 91 Date d'inscription mercredi 29 août 2007 Statut Membre Dernière intervention 8 octobre 2014 2
5 mai 2012 à 14:26
dubcek peux tu m'expliquer à quel niveau t'agrèges les lignes pour que je puisse l'adapter à mon script.
Ca n'a pas l'air de marcher dans l'état. C'est peut être normal.
0
dubcek Messages postés 18718 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 22 mars 2024 5 615
5 mai 2012 à 14:34
-F':'      on définit : comme séparateur
{x[$2, $3, $4]+=$5}        on somme les valeurs du champ 5 dans un tableau indexé par les champs 2, 3 et 4
END{for (n in x)           pour chaque index n (les 3 champs) du tableau x
{i=n ; gsub(SUBSEP, FS, n) ; print n FS x[i]}}             on sauve n, on convertit le séparateur des index de tableau ajouté par awk (SUBSEP=\034) en : et on imprime
0
Trop bavard a2p, ça fait penser à l'enregistrement des macros Excel.

$ cat aggreger234.pl
#!/usr/bin/perl
use strict;use warnings;

my %aggreger;

while(<DATA>){
/^.*?:((?:.*?:){3})(\d+)$/;
$aggreger{$1} += $2;
}

print "$_$aggreger{$_}\n" for sort keys %aggreger;

__END__
P1:A:TOTO:VAL1:62
P1:A:TOTO:VAL1:56
P1:A:TOTO:VAL2:5
P1:B:TOTO:VAL2:4
P1:A:TITI:VAL1:62
P2:A:TOTO:VAL2:59
P1:B:TITI:VAL6:5
P2:A:TOTO:VAL1:9
P2:B:BLABLA:VAL4:5
P2:B:TOTO:VAL2:61
P2:B:BLABLA:VAL4:51



$ perl aggreger234.pl
A:TITI:VAL1:62
A:TOTO:VAL1:127
A:TOTO:VAL2:64
B:BLABLA:VAL4:56
B:TITI:VAL6:5
B:TOTO:VAL2:65
0
Decon Messages postés 91 Date d'inscription mercredi 29 août 2007 Statut Membre Dernière intervention 8 octobre 2014 2
Modifié par Decon le 8/05/2012 à 10:38
Merci TMTOWTDI.
Ca marche comme je veux.
Peux tu cependant m'expliquer ce que tu fais!
0
Il s'agit de l'utilisation des hash (tableau associatif en perl)
Dubcek a utilisé aussi un tableau associatif mais en awk.
La traduction avec a2p n'est pas la manière la plus efficace d'écrire le code en perl selon moi.

#!/usr/bin/perl
use strict;use warnings;

my %aggreger; #déclaration de hash

while(<DATA>){                 # utilisation de handle DATA
                               # pour la lecture des données
  /^.*?:((?:.*?:){3})(\d+)$/;  # séparateur :
                               # utilisation de ? pour eviter 
                               # la gourmandise du quantificatuer *
                               # (?: - ouvre une paranthèse non-capturante
                               # P1: est donc non capturé
                               # on capture 3 fois un groupe de 
                               # n'importe quel caractère 
                               # jusqu'au 1er : rencontré
                               # il s'agit des champs 2,3 et 4 avec : inclus
                               # Ex: A:TOTO:VAL1: pour la 1ère ligne, etc.
                               # Ca sera la clé de notre Hash ( $1 )
                               # La 2ème capture ($2) 
                               # sera la valeur numérique

  $aggreger{$1} += $2;         # Sachant que la clé d'un hash est unique
                               # il suffit d'incrementer sur la clé 
                               # les valeurs numériques correspondantes

}

print "$_$aggreger{$_}\n" for sort keys %aggreger; # affichage

# DATA lit tout ce qui se trouve après __END__

__END__
P1:A:TOTO:VAL1:62
P1:A:TOTO:VAL1:56
P1:A:TOTO:VAL2:5
P1:B:TOTO:VAL2:4
P1:A:TITI:VAL1:62
P2:A:TOTO:VAL2:59
P1:B:TITI:VAL6:5
P2:A:TOTO:VAL1:9
P2:B:BLABLA:VAL4:5
P2:B:TOTO:VAL2:61
P2:B:BLABLA:VAL4:51
0
Decon Messages postés 91 Date d'inscription mercredi 29 août 2007 Statut Membre Dernière intervention 8 octobre 2014 2
Modifié par Decon le 9/05/2012 à 01:19
Super! Merci TMTOWTDI.
0