Rápida eliminação de linhas duplicadas em vários arquivos

5

Eu tenho uma quantidade enorme de dados em que cada linha (data) deve ser única.

Existem muitos arquivos em uma pasta em que isso já é verdade. São cerca de 15 GB divididos em aproximadamente 170 arquivos com linhas de 1000000. Vamos chamar essa pasta foo .

Agora há uma segunda pasta ( bar ) com ainda mais dados: Em cada arquivo, não há várias entradas. A interseção de dois arquivos em bar não está necessariamente vazia. Existem aproximadamente 15k linhas em cada um dos arquivos (e existem vários milhares de arquivos em bar ).

Agora estou usando

awk 'NR==FNR{a[$0]=$0;next}!a[$0]' foo/file bar/file > tmp
mv tmp bar/file

e um loop sobre todos os arquivos em foo e um loop sobre todos os arquivos em bar . Eu quebro o loop sobre foo se o bar/file estiver vazio. Eu paralelizei isso travando (para uso em vários nós) e execução paralela (em cada nó). Mas ainda assim, isso precisa de muito tempo.

Quais são as possibilidades de melhorar o desempenho? Qual é o tamanho ideal dos arquivos em foo ? Claro que isso é dependente da máquina (RAM / CPU / armazenamento), mas o que é uma boa regra aqui?

tl; dr : foo contém linhas de dados exclusivas, bar contém linhas de dados que podem aparecer várias vezes em bar e foo . Elimine duplicatas em bar , de forma que elas possam ser mescladas com foo

[Update] Não há linhas vazias [/ Update]

    
por stefan 11.09.2012 / 12:29

2 respostas

4

Não sei se entendi sua pergunta, mas seu código pode ser otimizado para:

awk 'NR==FNR{a[$0]="";next}; !($0 in a)' foo/file bar/file > tmp

(você teve problemas com linhas vazias ou linhas resolvendo "0" nelas, eu acho)

Se os arquivos estiverem classificados, você poderia fazer:

comm -13 foo/file bar/file > tmp

Se não forem (sintaxe ksh93. zsh ou bash):

comm -13  <(sort foo/file) <(sort bar/file) > tmp

(não necessariamente mais rápido que a solução awk)

Além disso, especialmente com o GNU awk, você pode obter um melhor desempenho definindo a localidade como C / POSIX:

LC_ALL=C awk ...
    
por 11.09.2012 / 14:09
0

Eu tinha vários arquivos de poucos MB e tentei isso, o que funciona para mim:

sort *.csv | uniq -d 

Isso lhe dará registros duplicados de seu arquivo e, em seguida, você poderá redirecionar a saída para um único arquivo para obter registro duplicado e remover -d fornecerá a você todos os registros únicos.

    
por 29.04.2015 / 07:39