Supondo que seus dados de entrada estejam em um arquivo chamado "notas", tente:
$ awk 'BEGIN{ PROCINFO["sorted_in"]="@ind_str_desc"} NR==1{next} {m[$1]; n[$2]; g[$2,$1]=$3} END{for (name in n) {printf "%s",name; for (month in m) printf " %s",g[name,month]; print""}}' grades | column -t
Steve 83 39
Sam 58 77
Mark 71 38
John 64 47
A saída tem uma linha por aluno com as notas apresentadas em ordem decrescente de mês.
Para aqueles que preferem o código espalhado por várias linhas:
gawk '
BEGIN{ PROCINFO["sorted_in"]="@ind_str_desc"}
NR==1{
next
}
{
m[$1]
n[$2]
g[$2,$1]=$3
}
END{
for (name in n) {
printf "%s",name
for (month in m)
printf " %s", g[name,month]
print""
}
}
' grades | column -t
Como funciona
-
BEGIN{ PROCINFO["sorted_in"]="@ind_str_desc"}
Isto diz ao awk que queremos matrizes ordenadas em índices. Este é um recurso do GNU.
-
NR==1{next}
Isso diz ao awk para pular a primeira linha. Se você quiser adicionar um cabeçalho para o arquivo de saída, poderíamos fazê-lo aqui.
-
m[$1]
Isso diz ao awk para adicionar uma entrada para o mês atual na matriz associativa
m
. Não precisamos atribuir um valor porque simplesmente usaremos isso para rastrear quais meses estão presentes na entrada. -
n[$2]
Isto diz ao awk para adicionar uma entrada para o nome do aluno no array associativo
n
. Não precisamos atribuir um valor porque simplesmente usaremos isso para rastrear quais meses estão presentes na entrada. -
g[$2,$1]=$3
Isso atribui a nota como o valor sob a chave do nome do aluno, mês na matriz associativa
g
. -
END{for (name in n) {printf "%s",name; for (month in m) printf " %s",g[name,month]; print""}}
Depois de chegarmos ao final do arquivo, imprimimos todos os nomes e notas para cada aluno.
-
column -t
Este passo opcional torna a saída bonita.