$ sort -k 3,3r session.log | awk '!seen[$2]++ { print }'
9 u1 2018-08-12 pass
6 u4 2018-07-11 pass
2 u2 2018-06-15 pass
3 u3 2018-05-18 pass
(O { print }
pode ser removido completamente, só estou incluindo para mostrar o que acontece. A ação padrão é imprimir todo o registro de entrada se a condição for verdadeira.)
Isso classifica o arquivo que você possui, diminuindo as datas (a data mais recente primeiro). O programa awk
lê os dados classificados e imprime a primeira entrada encontrada para cada usuário. A variável seen
é uma matriz / hash associativa que usa os nomes de usuários como chaves. Se seu valor for zero para um usuário, esse usuário ainda não foi visto e, portanto, a linha do arquivo será impressa.
Seu código com minhas anotações:
# get list of unique usernames from log:
( awk {print} session.log | cut -f2 -d' ' | sort | uniq ) > store.txt
# shorter equivalent:
# cut -d ' ' -f2 <session.log | sort -u >store.txt
# loop over the usernames:
for line in $(cat "store.txt")
do
# get entries related to this user:
grep "$line" session.log > "$line.txt"
# echo the last entry:
echo $(sort -k3 "$line.txt" | awk 'END{print}')
# shorter equivalent of both of the above commands:
# awk -v user="$line" '$2 == user { print }' session.log | sort -k3,3 | tail -n 1
done
rm -f store.txt
Portanto, uma abordagem alternativa baseada em seu loop de shell:
cut -d ' ' -f2 <session.log | sort -u |
while read username; do
awk -v user="$username" '$2 == user { print }' session.log | sort -k 3,3 | tail -n 1
done
Novamente, o { print }
pode ser deixado de fora do script awk
acima.
Isso ainda classifica subconjuntos de log de sessão uma vez para cada usuário, o que é uma espécie de desperdício.
Pré-classificando o registro diminuindo as datas:
sort -k3,3r -o sorted.log session.log
cut -d ' ' -f2 <session.log | sort -u |
while read username; do
awk -v user="$username" '$2 == user { print; exit }' sorted.log
done
rm sorted.log
Isso ainda requer que digitalizemos o log a partir do topo uma vez por usuário. A melhoria natural é permitir que awk
acompanhe o que os usuários viram e quais usuários não foram vistos, o que dá a minha resposta no topo.