quinta-feira, 26 de julho de 2007

Identificando linhas repetidas em varios arquivos

Vamos imaginar dois arquivos bem simples e tres formas de identificar as linhas que aparecem em ambos:

$ cat arq1
oi
awk
ciencia
oi zoi

$ cat arq2
luxo
awk
oi
luxo


Simples de perceber que as linhas 'oi' e 'awk' se repetem. Poderiamos pensar em uma poderosa união de sort + uniq
$ sort <(sort arq1 | uniq) <(sort arq2 | uniq) | uniq -d
awk
oi


Ou podemos abordar arrays em AWK (elegante, não?)
$ awk 'NR==1{ base=FILENAME } 
base == FILENAME {linhas[$0]++}
base != FILENAME && linhas[$0] { print }' arq1 arq2
awk
oi


Ou podemos usar o bom e velho grep:
$ grep -xf arq1 arq2
awk
oi

Qual a melhor abordagem? Ai depende de cada um :)

Veja toda a aula que deu origem à estes scritps aqui.

3 comentários:

Denis disse...

Imagino que para um busca menor de 16milhoes a melhor seria o grep, pois nao utiliza os redirects como no caso do SORT. Se nao o AWK.

Denis disse...

Imagino que para um busca menor de 16milhoes a melhor seria o grep, pois nao utiliza os redirects como no caso do UNIQ.

Tiago Peczenyj disse...

Denis, mantive os seus dois comentarios, apesar de serem semelhantes.

Saca só, se pensarmos em 16 milhões de linhas, temos q pensar exatamente no que queremos. se for para encontrar as linhas exatas, talvez o grep seja mais rápido, porém acredito que vai ter muito acesso a disco.

Se separarmos os arquivos em partes, de acordo com os caracteres iniciais, acho que a pesquisa pode ficar bem mais rapida -- se estiverem ordenados então vai q é um tapa.

Ou talvez seja o momento de pensar em algoritmos mais complexos :)