Nesta aula, vamos explorar dois comandos fundamentais para manipulação de dados em shell script: sort e uniq. Eles permitem ordenar linhas de texto e remover duplicatas, respectivamente, sendo essenciais para processamento de arquivos de log, listas e saídas de comandos. Combinados com pipes, formam a base de pipelines de dados eficientes.

Dominar esses comandos é crucial para automatizar tarefas de análise e organização de dados no terminal. Compreender suas opções e comportamentos evita erros comuns e permite extrair informações rapidamente.

sort (numérico, reverso, por campo)

O comando sort ordena linhas de texto em ordem alfabética por padrão. No entanto, ele oferece diversas opções para ordenação numérica, reversa e por campos específicos, tornando-o extremamente flexível.

Para ordenar numericamente, use a opção -n. Para ordem reversa, use -r. A opção -k permite especificar o campo (coluna) a ser usado como chave de ordenação. Campos são delimitados por espaços ou tabulações por padrão, mas o delimitador pode ser alterado com -t.

Exemplo: ordenar um arquivo de números:

$ cat numbers.txt
10
2
33
4
1
$ sort -n numbers.txt
1
2
4
10
33

Ordenar reversamente: sort -nr numbers.txt.

Ordenar por campo: suponha um arquivo com nomes e idades:

$ cat pessoas.txt
João 30
Maria 25
Ana 35
$ sort -k2 -n pessoas.txt
Maria 25
João 30
Ana 35

A opção -k2 indica o segundo campo (idade). Combinar -k com -n e -r é comum. Para delimitadores personalizados, use -t (ex: -t':' para CSV).

Boas práticas: sempre verifique o locale; para ordenação consistente, use LC_ALL=C sort. O sort é estável (-s) mantém ordem original para chaves iguais.

uniq

O comando uniq remove linhas duplicadas consecutivas. Por isso, é frequentemente usado após sort para garantir que duplicatas estejam adjacentes. Sem opções, ele exibe apenas a primeira ocorrência de cada linha repetida.

Exemplo:

$ cat cores.txt
azul
verde
azul
amarelo
verde
$ sort cores.txt | uniq
amarelo
azul
verde

Opções importantes: -c conta ocorrências, -d mostra apenas duplicatas, -u mostra apenas linhas únicas (não duplicadas).

Exemplo com contagem:

$ sort cores.txt | uniq -c
      1 amarelo
      2 azul
      2 verde

Note que uniq compara linhas inteiras. Para ignorar campos, use -f N (pula N campos) ou -s N (pula N caracteres).

Combinando com pipes

Pipes (|) permitem encadear comandos, criando pipelines poderosos. A combinação sort | uniq é clássica para listar itens únicos ordenados. Exemplo: listar processos únicos em execução:

$ ps aux | awk '{print $11}' | sort | uniq
[comando]
bash
chrome
...

Outro exemplo: contar IPs únicos em um arquivo de log:

$ cat access.log | awk '{print $1}' | sort | uniq -c | sort -rn
    120 192.168.1.1
     45 10.0.0.2
      3 172.16.0.1

O pipe leva a saída de um comando para a entrada do próximo, permitindo processamento em etapas. Sempre verifique se o comando anterior produz saída textual.

Contagem

A opção -c do uniq é a principal ferramenta para contagem de ocorrências. Para obter uma contagem ordenada (mais frequente primeiro), combine com sort -rn.

Exemplo completo: arquivo de palavras:

$ cat palavras.txt
casa
carro
casa
moto
carro
casa
$ sort palavras.txt | uniq -c | sort -rn
      3 casa
      2 carro
      1 moto

Para contar caracteres ou palavras, use wc, mas uniq -c conta linhas. Se precisar contar palavras únicas, use tr para quebrar em linhas:

$ echo "casa carro casa moto carro casa" | tr ' ' '\n' | sort | uniq -c | sort -rn
      3 casa
      2 carro
      1 moto

Boas práticas: lembre-se de que uniq -c adiciona espaços à esquerda; para processamento posterior, use awk ou sed para limpar.

Boas práticas e observações finais

Sempre use sort antes de uniq para garantir que duplicatas sejam adjacentes. Evite usar uniq em arquivos grandes sem ordenar, pois só remove consecutivas. Para ordenação numérica, lembre-se de -n; caso contrário, 10 vem antes de 2. Use LC_ALL=C para evitar problemas de locale. Teste seus pipelines com arquivos pequenos primeiro.

Referências

Exercícios

  1. Dado o arquivo numeros.txt com o conteúdo:
    10 2 33 4 1 10 2
    Use sort e uniq para listar os números únicos em ordem crescente.

    ✓ Resposta:
    sort -n numeros.txt | uniq
    Saída: 1 2 4 10 33
  2. Ordene o arquivo pessoas.txt (formato: nome idade) por idade de forma decrescente. Conteúdo:
    João 30 Maria 25 Ana 35

    ✓ Resposta:
    sort -k2 -nr pessoas.txt
    Saída: Ana 35 João 30 Maria 25
  3. Conte quantas vezes cada IP aparece no arquivo ips.txt abaixo, exibindo em ordem decrescente de frequência.
    192.168.1.1 10.0.0.2 192.168.1.1 172.16.0.1 10.0.0.2 192.168.1.1

    ✓ Resposta:
    sort ips.txt | uniq -c | sort -rn
    Saída: 3 192.168.1.1 2 10.0.0.2 1 172.16.0.1
  4. Extraia apenas as linhas duplicadas (que aparecem mais de uma vez) do arquivo cores.txt:
    azul verde azul amarelo verde

    ✓ Resposta:
    sort cores.txt | uniq -d
    Saída: azul verde
  5. Use um pipeline para contar quantas vezes cada palavra aparece na frase: o rato roeu a roupa do rei de roma. Dica: use tr para substituir espaços por novas linhas.

    ✓ Resposta:
    echo "o rato roeu a roupa do rei de roma" | tr ' ' '\n' | sort | uniq -c | sort -rn
    Saída: 2 o 1 rato 1 roeu 1 roupa 1 rei 1 roma 1 do 1 de 1 a