terça-feira, 26 de março de 2013

Como encontrar valores distintos em arquivos de texto

Recebi um arquivo de texto com quase 300MB e 300 mil linhas para uma carga que executo mensalmente. Esse arquivo veio com uma alteração de formato e também com valores novos numa coluna crítica.

Para verificar se a alteração no formato não tinha provocado uma falha na carga, resolvi inspecionar o arquivo com as ferramentas que o Linux oferece.

Descobri uma maneira bastante simples de enumerar os valores distintos de uma coluna:

cut -c N-M arquivo.txt | sort | uniq

Os valores N e M indicam, respectivamente, a coluna inicial (baseado em 1) e a coluna final do trecho interessante de cada linha. Com um arquivo compactado, fiz o seguinte:

gunzip -c arquivo.txt.gz | cut -c N-M | sort | uniq

O cut pareceu-me um pouco lento, então resolvi verificar se o Perl pode fazer o mesmo com maior velocidade.

perl -pe '$_=substr($_, C, L)."\n"' arquivo.txt | sort | uniq

E, de fato, a solução, embora mais complexa, é mais rápida. Neste caso, C indica a coluna inicial (baseada em 0) e L o tamanho do campo (ou seja, C=N-1 e L=M-N+1).

Posso usar o perl com arquivos compactados assim:

gunzip -c arquivo.txt.gz | perl -pe '$_=substr($_, C, L)."\n"' | sort | uniq

Se eu quisesse apenas saber o número de valores distintos, bastaria adicionar o wc ao fim:

cut -c N-M arquivo.txt | sort | uniq | wc -l

E, com isso, pude confirmar que tinha carregado os dados corretamente. É interessante que o comando uniq não busca valores distintos, ele apenas elimina linhas sucessivas iguais. Por isso, é preciso usar também o comando sort.

Nenhum comentário: