Estou trabalhando com um arquivo de texto de várias linhas (.csv) que contém 7 colunas.
Cada linha contém o que "deveria" ser um id exclusivo. Há também algumas colunas de data, uma das quais é a data da "última modificação".
Descobri que o que deveria ser id "único" é realmente repetido de vez em quando e é um problema que preciso resolver removendo todos, exceto um.
Eu tenho um exemplo usando gawk abaixo, mas existe uma maneira de usar gawk, awk ou grep etc para excluir todas as linhas duplicadas, MAS com exceção da "mais recentemente" modificada? Então, com alguma lógica sobre o que vai e fica.
Como exemplo, esta extração csv tem duas linhas. Cada campo, exceto um, é o mesmo. O número de identificação sendo "o mesmo" significa que é uma "duplicata" para meus propósitos.
Ambas as linhas não são completamente iguais.
A data no campo final (7º) do arquivo csv torna uma entrada mais antiga que a outra.
ID12345,Here is some text,ABCDEFG,7,9,2022-08-18 20:15:00,2022-08-26 17:32:00
ID12345,Here is some text,ABCDEFG,7,9,2022-08-18 20:15:00,2022-09-11 22:15:00
É possível gawk, cat, grep, cut, awk etc no arquivo e:
a) identificar qualquer coisa com um ID duplicado. b) reter apenas as duplicatas com a data "mais recente" no último campo.
Idealmente, eu precisaria da primeira linha deixada no lugar porque ela contém os títulos do csv que está sendo alimentado em um banco de dados.
É por isso que isso quase funciona bem:
gawk -i inplace '!a[$0]++' *.csv
Na verdade, parece remover duplicatas deixando uma linha no local, mas não tem lógica para decidir o que deixar no local com base no valor de data mais antigo no campo final.
Você pode por favor ajudar...
Supondo que você queira apenas testar duplicatas em cada arquivo, não em todos os arquivos, e que você não se importe em preservar a ordem de entrada de seus dados, ele fará o que você deseja usando qualquer versão de ferramentas POSIX obrigatórias para que funcione em qualquer caixa Unix:
Por exemplo:
Observe que apenas
sort
acima tem que lidar com toda a entrada de uma só vez, as outras ferramentas lidam apenas com 1 linha de cada vez esort
são projetadas para lidar com arquivos grandes usando paginação de demanda, etc. se seus arquivos de entrada forem enormes.Se você deseja manter a ordem da linha de entrada, pode alterar o acima para aplicar o idioma DSU para fazer isso:
mas requer um segundo
sort
após as linhas terem sido selecionadas para que a entrada volte à sua ordem original.Se você realmente quisesse fazer tudo usando uma única chamada para GNU awk mantendo a ordem de entrada, seria:
Esse script gawk manteria a ordem de entrada original, mas teria que ler todos os arquivos de entrada na memória.
Com GNU awk para a função mktime() :
consulte Usando ordens de varredura de matriz predefinidas com gawk (
PROCINFO["sorted_in"]
) para definir as travessias de loop for padrão de uma matriz durante a saída.Combinando
sort
comawk
=> Inversamente ordena pelo sétimo campo (o campo de data), ou seja, as entradas mais recentes primeiro. Em seguida, imprime linhas apenas com o primeiro ID exclusivo.
Advertências: vírgulas extras nas strings; se a mesma data aparecer para o mesmo ID, a linha será tomada conforme definido pela classificação reversa; strings de data que não usam zeros à esquerda/preenchidos ou formatos mistos