Aggreger valeurs des lignes ayant des champs
Résolu
Decon
Messages postés
91
Date d'inscription
Statut
Membre
Dernière intervention
-
Decon Messages postés 91 Date d'inscription Statut Membre Dernière intervention -
Decon Messages postés 91 Date d'inscription Statut Membre Dernière intervention -
Bonjour,
Soit le fichier FIC de contenu:
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:
Merci d'avance.
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.
A voir également:
- Aggreger valeurs des lignes ayant des champs
- Partager des photos en ligne - Guide
- Word mettre à jour tous les champs - Forum Word
- Echec mise à jour champs Word ✓ - Forum Word
- Cette valeur ne correspond pas aux restrictions de validation des données pour cette cellule ✓ - Forum MacOS
- Afficher des lignes masquées excel ✓ - Forum Excel
10 réponses
hello
avec quel outil ? awk ?
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 $
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?
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?
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}; }
$
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
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.
Ca n'a pas l'air de marcher dans l'état. C'est peut être normal.
-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
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
$ 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
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.
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