Em Perl
perl -F';' -lane 'push @{$h{join ";",@F[0..2]}},$F[3];
END{
for(sort keys %h){
print "$_: ". join ",",@{$h{$_}};
}
}' your_file
Você deve ser capaz de fazer algo semelhante em awk
usando matrizes associativas, mas eu não sou muito versado em awk
, então não posso contribuir com código real.
Explicação
Aqui está uma versão expandida do código acima que usa o mínimo de "mágica" possível:
open($FH,"<","your_file");
while($line=<$FH>){ # For each line in the file (accomplished by -n)
chomp $line; # Remove the newline at the end (done by -l)
# The ; is set by -F and storing the split in @F done by -a
@F = split /;/,$line # Split the line into fields on ;
$app_id = join ";",@F[0..2]; # AppID is the first 3 fields
push @{$h{$app_id}},$F[3]; # The 4th field is added onto the hash
} # The whole file has been read at this point.
foreach $key (sort keys %h){ # Sort the hash by AppID
print "$key: " . join ",",@{h{$key}}."\n"; # Print the array values
# The newline ("\n") added at the end is also done by -l
}
Agora só resta a declaração push
para explicar em mais detalhes:
-
push
é normalmente usado para adicionar elementos a uma variável de matriz. Por exemplo:push @a,$x
acrescenta o conteúdo da variável
$x
ao array@a
. -
O loop que lê o arquivo linha por linha está preenchendo uma tabela de hash (
%h
). As chaves para o hash são os AppIDs e o valor que corresponde a cada chave é um array contendo todos os IDs de usuário associados a esse AppID. Este é um array anônimo (não tem nome); em Perl isso é implementado como uma referência de matriz (um pouco semelhante aos ponteiros C). E como o valor de%h
que corresponde ao AppID$app_id
é denotado por$h{$app_id}
, o acréscimo na matriz Perl sigial (@
) trata o valor de hash como uma matriz (desrefere a referência da matriz) e envia o ID do usuário atual para ele. -
Uma alternativa que pode parecer menos "Perlish" para você seria concatenar o quarto campo com o valor atual:
while(...) { ... $h{$app_id} = $h{$app_id} . ",$F[3]" } foreach $key (sort keys %h) { print "$_: $h{$_}" }
em que
.
em Perl é o operador de concatenação de strings.
Observe que, no código de explicação, omiti o wrapper perl -e '...'
para que o realce da sintaxe possa chegar ao código e torná-lo mais legível.