Exclua linhas consecutivas em CSV com valores duplicados em um campo, mas mantenha a última linha

4

Eu tenho um longo arquivo CSV com duas colunas, que inclui execuções de duplicatas consecutivas como esta:

...
1500,1533
1554,1678
1554,1703
1554,1728
1593,1766
...

Preciso excluir todas essas duplicatas, exceto a última, para que a saída do exemplo acima seja:

...
1500,1533
1554,1728
1593,1766
...

Também preciso manter o restante das linhas no arquivo em sua ordem original.

Eu tentei tac file.csv | sort -k1,1 -r -u -t,

mas isso não deu o resultado desejado, e as funções baseadas em classificação atrapalharam minha ordem de linha.

    
por knovice 24.02.2016 / 19:30

3 respostas

3

com sed :

sed '$!N;/\(.*,\).*\n/!P;D' infile

N significa que sempre há duas linhas consecutivas no espaço de padrão e sed P rim a primeira delas somente se o primeiro campo nessa linha não for o mesmo que o primeiro campo na segunda linha . Então D remove a primeira linha do espaço padrão e reinicia o ciclo.

Outra maneira com gnu datamash (supondo que seu arquivo esteja classificado como datamash requer entrada classificada):

datamash -t ',' -g 1 last 2 <infile

Este g grupos da entrada , delimitada pelo campo 1 st, imprimindo apenas o valor last (da coluna 2 nd) de cada grupo.

Se o seu arquivo não estiver classificado, datamash poderá classificá-lo via -s :

datamash -t ',' -s -g 1 last 2 <infile

mas isso significa que a ordem inicial das linhas não será preservada. Então, isso pode não fazer o que você quer. Nesse caso, você poderia usar sed / awk / perl etc ...

    
por 24.02.2016 / 19:53
2

E um alternativo awk:

 awk -F, 'NR==1{old=$0;check=$1}NR>1 && $1 != check {print old}{old=$0;check=$1}END{print old}' knovice
1500,1533
1554,1728
1593,1766
    
por 24.02.2016 / 20:01
1

Aqui está outra abordagem awk (obrigado @ Glenn ):

 tac file | awk -F, 'awk -F, '!seen[$1]++' | tac

O -F, define o delimitador. Em awk , a ação padrão quando uma expressão é avaliada como true é imprimir a linha atual. !seen[$1] será verdadeiro quando o primeiro campo não existir na matriz seen . No entanto, como também estamos criando com seen[$1]++ , isso só será falso na primeira vez que for visto. O resultado é que somente a primeira das duplicatas será impressa.

Como o script acima manterá o primeiro e não o último de cada execução de duplicatas, as duas tac chamadas são um truque feio para reverter o pedido e mantê-lo em último lugar. Como há dois, o pedido final não será alterado.

    
por 24.02.2016 / 20:08