Já que a entrada parece estar agrupada / ordenada pela segunda coluna, isso deve ser bem simples e não requer manter e ordenar todo o conjunto de dados na memória, apenas dois registros em um tempo. 1
Primeiramente, pensei em uma solução Awk, mas achei desastroso lidar com arrays e delimitadores de campo não-brancos. Então eu decidi por um programa Python curto:
#!/usr/bin/python3
import sys
DELIMITER = ','
def remove_duplicates(records):
prev = None
for r in records:
r = (int(r[0]), int(r[1]), int(r[2]), float(r[3]), int(r[4]))
if prev is None:
prev = r
elif r[1] != prev[1]:
yield prev
prev = r
elif r[3] > prev[3]:
prev = r
if prev is not None:
yield prev
def main():
for r in remove_duplicates(
l.rstrip('\n').rsplit(DELIMITER) for l in sys.stdin
):
print(*r, sep=',')
if __name__ == '__main__':
main()
No meu sistema, ele tem uma taxa de transferência de aproximadamente 250.000 registros ou 5 MB por segundo de CPU.
Uso
python3 remove-duplicates.py < input.txt > output.txt
O programa não consegue lidar com cabeçalhos de coluna, então você precisa desmembrá-los:
tail -n +2 < input.txt | python3 remove-duplicates.py > output.txt
Se você quiser adicioná-los de volta ao resultado:
{ read -r header && printf '%s\n' "$header" && python3 remove-duplicates.py; } < input.txt > output.txt
1 Essa é uma grande vantagem em relação às chaves de aço e do Waltinator abordagens para conjuntos de dados que não se encaixam na memória principal.