Pergunta

Eu tenho arquivos com esse tipo de linhas duplicadas, onde apenas o último campo é diferente:

OST,0202000070,01-AUG-09,002735,6,0,0202000068,4520688,-1,0,0,0,0,0,55
ONE,0208076826,01-AUG-09,002332,316,3481.055935,0204330827,29150,200,0,0,0,0,0,5
ONE,0208076826,01-AUG-09,002332,316,3481.055935,0204330827,29150,200,0,0,0,0,0,55
OST,0202000068,01-AUG-09,003019,6,0,0202000071,4520690,-1,0,0,0,0,0,55

Preciso remover a primeira ocorrência da linha e deixar a segunda.

Eu tentei:

awk '!x[$0]++ {getline; print $0}' file.csv

Mas não está funcionando como pretendido, pois também está removendo linhas não duplicadas.

Foi útil?

Solução

Se seus quase duplicatos forem sempre adjacentes, você poderá comparar com a entrada anterior e evitar a criação de uma matriz associativa potencialmente enorme.

#!/bin/awk -f
{
    s = substr($0, 0, match($0, /,[^,]*$/))
    if (s != prev) {
        print prev0
    }
    prev = s
    prev0 = $0
} 
END {
    print $0
}

Editar: Mudou o script para que ele imprima o último em um grupo de quase duplicatos (não tac precisava).

Outras dicas

#!/bin/awk -f
{
    s = substr($0, 0, match($0, /,[^,]+$/))
    if (!seen[s]) {
        print $0
        seen[s] = 1
    }
}

Como estratégia geral (eu não sou muito awk pro, apesar de ter aulas com Aho), você pode tentar:

  1. Concatenar todos os campos, exceto o último.
  2. Use essa string como uma chave para um hash.
  3. Armazene toda a linha como o valor para um hash.
  4. Quando você processou todas as linhas, atravesse o hash imprimindo os valores.

Isso não é específico e não posso facilmente fornecer nenhum código de exemplo, mas é isso que eu tentaria primeiro.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top