Aggreger valeurs des lignes ayant des champs
Résolu
Decon
Messages postés
95
Statut
Membre
-
Decon Messages postés 95 Statut Membre -
Decon Messages postés 95 Statut Membre -
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
- Insérer des lignes pour écrire dans word - Forum Word
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