eu tenho um arquivo csv para data de login dos usuários
user1,2019-05-21
user1,2019-05-22
user1,2019-05-23
user2,2019-05-20
user2,2019-05-21
user3,2019-05-24
user3,2019-05-29
user4,2019-05-25
user4,2019-05-28
eu preciso dele no formato abaixo.
user1,2019-05-23
user2,2019-05-21
user3,2019-05-29
user4,2019-05-28
tenteiawk -F, '!a[$1]++', o que está me dando o primeiro valor e não o último.
Responder1
$ sort -t, -k1,1 -k2,2r file | sort -t, -u -k1,1
user1,2019-05-23
user2,2019-05-21
user3,2019-05-29
user4,2019-05-28
O primeiro sort
classifica os dados por usuário e inverte as datas. A saída dessa etapa se parece com
user1,2019-05-23
user1,2019-05-22
user1,2019-05-21
user2,2019-05-21
user2,2019-05-20
user3,2019-05-29
user3,2019-05-24
user4,2019-05-28
user4,2019-05-25
O segundo sort
classifica apenas os usuários e mantém apenas uma instância das linhas de cada usuário (a primeira encontrada).
Responder2
Conforme apontado nos comentários, isso já foi perguntado antes e várias respostas foram fornecidas. Eu gostaria de adicionar mais um:
sort -r input.csv | awk -F, '!a[$1]++' | sort
Execução de teste:
$ sort -r input.csv | awk -F, '!a[$1]++' | sort
user1,2019-05-23
user2,2019-05-21
user3,2019-05-29
user4,2019-05-28
Explicação:
Você já sabe imprimir a primeira ocorrência da primeira coluna; se você quiser o último, não precisa mais coçar a cabeça: basta classificar e inverter a lista com sort -r
. Como última etapa, e somente se você precisar que o resultado seja classificado, canalize novamente para sort
.
Sem tubos:
Você também pode resolver isso com um único comando. Se o arquivo de entrada estiver classificado (como no seu exemplo):
awk -F, '{a[$1]=$2}END{for(k in a){print k","a[k]}}' input.csv
de outra forma:
awk -F, '$2>a[$1]{a[$1]=$2}END{for(k in a){print k" "a[k]}}' input.csv