Ordenando e filtrando: sort e uniq
Esta aula ensina a ordenar e filtrar dados no shell usando os comandos sort e uniq. Você aprenderá a ordenar linhas numericamente, em ordem reversa e por campos específicos, além de remover duplicatas e combinar esses comandos com pipes para análises eficientes.
Nesta aula, vamos explorar dois comandos fundamentais para manipulação de texto no shell: sort e uniq. Eles permitem organizar e limpar dados de forma rápida, seja em arquivos ou na saída de outros comandos, usando pipes. Com sort, você pode ordenar linhas de várias maneiras; com uniq, pode remover ou contar ocorrências consecutivas. Juntos, são ferramentas essenciais para análise de logs, processamento de listas e preparação de dados.
sort (numérico, reverso, por campo)
O comando sort ordena as linhas de um arquivo ou da entrada padrão. Por padrão, a ordenação é alfabética (baseada na ordem lexicográfica). Para ordenação numérica, use a opção -n. Para inverter a ordem, use -r. É possível ordenar por um campo específico usando -k.
Exemplo: suponha que temos um arquivo numeros.txt com os números 10, 2, 33, 4, 5 (um por linha).
$ cat numeros.txt
10
2
33
4
5
$ sort -n numeros.txt
2
4
5
10
33
$ sort -nr numeros.txt
33
10
5
4
2
Para ordenar por campo, use -k especificando o número do campo (campos são separados por espaços ou tabulações). Exemplo: um arquivo pessoas.txt com nome e idade:
$ cat pessoas.txt
João 30
Maria 25
Ana 28
$ sort -k2 -n pessoas.txt
Maria 25
Ana 28
João 30
A opção -t permite definir um separador diferente (ex.: -t: para CSV).
uniq
O comando uniq remove linhas duplicadas consecutivas. Ele não remove duplicatas não consecutivas a menos que você ordene os dados primeiro. Portanto, é comum usar sort | uniq. A opção -c conta as ocorrências de cada linha.
Exemplo com um arquivo frutas.txt:
$ cat frutas.txt
maçã
banana
maçã
laranja
banana
banana
$ sort frutas.txt | uniq
banana
laranja
maçã
$ sort frutas.txt | uniq -c
3 banana
1 laranja
2 maçã
Outras opções: -d mostra apenas linhas duplicadas, -u mostra apenas linhas únicas.
Combinando com pipes
A verdadeira potência surge ao combinar sort e uniq com outros comandos via pipes. Por exemplo, para listar os processos em execução e contar quantas vezes cada comando aparece:
$ ps aux | awk '{print $11}' | sort | uniq -c | sort -rn | head -5
45 /usr/bin/bash
12 /usr/bin/ps
8 /usr/bin/grep
3 /usr/bin/awk
2 /usr/bin/head
Outro exemplo: extrair IPs de um arquivo de log e contar acessos:
$ grep '192\.168\.' access.log | awk '{print $1}' | sort | uniq -c | sort -rn
Contagem
A contagem de ocorrências é feita principalmente com uniq -c. O resultado mostra o número de ocorrências seguido da linha. Para ordenar por frequência, use sort -rn (reverso numérico). Exemplo:
$ cat dados.txt
A
B
A
C
B
B
$ sort dados.txt | uniq -c | sort -rn
3 B
2 A
1 C
Você pode também usar awk para contagens mais complexas, mas sort | uniq -c é simples e eficiente.
Referências
- GNU Coreutils: sort invocation
- GNU Coreutils: uniq invocation
- man sort (linux.die.net)
- man uniq (linux.die.net)
- GNU Coreutils manual
Boas práticas
Sempre verifique se os dados estão bem formatados (ex.: sem espaços extras). Use -t para separadores não padrão. Lembre-se de que uniq só remove duplicatas consecutivas; portanto, sempre ordene antes de usar uniq se quiser remover todas as duplicatas. Para grandes volumes, considere o uso de sort -S para controlar o uso de memória.
Exercícios
-
Dado o arquivo
numeros.txtcom os números 10, 2, 33, 4, 5 (um por linha), usesortpara exibir em ordem decrescente.✓ Resposta:sort -nr numeros.txt -
Crie um comando que ordene o arquivo
pessoas.txt(nome e idade separados por espaço) pela idade (segundo campo) em ordem crescente.✓ Resposta:sort -k2 -n pessoas.txt -
Use
sorteuniqpara listar as linhas únicas do arquivofrutas.txt(maçã, banana, maçã, laranja, banana, banana) em ordem alfabética.✓ Resposta:sort frutas.txt | uniq -
Conte quantas vezes cada fruta aparece em
frutas.txte exiba em ordem decrescente de frequência.✓ Resposta:sort frutas.txt | uniq -c | sort -rn -
Dado o comando
ps aux, filtre apenas a coluna do comando (11ª coluna), ordene, conte as ocorrências e mostre os 3 comandos mais frequentes.✓ Resposta:ps aux | awk '{print $11}' | sort | uniq -c | sort -rn | head -3