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

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

  1. Dado o arquivo numeros.txt com os números 10, 2, 33, 4, 5 (um por linha), use sort para exibir em ordem decrescente.

    ✓ Resposta:
    sort -nr numeros.txt
  2. 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
  3. Use sort e uniq para listar as linhas únicas do arquivo frutas.txt (maçã, banana, maçã, laranja, banana, banana) em ordem alfabética.

    ✓ Resposta:
    sort frutas.txt | uniq
  4. Conte quantas vezes cada fruta aparece em frutas.txt e exiba em ordem decrescente de frequência.

    ✓ Resposta:
    sort frutas.txt | uniq -c | sort -rn
  5. 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