Linux / Comando uniq: remover e contar repetições consecutivas

uniq reúne linhas iguais que estão lado a lado: pode manter uma linha por grupo ou contar suas ocorrências. Uma repetição distante permanece separada. Para reunir valores iguais do arquivo inteiro, normalmente você ordena a entrada antes, mas essa etapa muda a ordem dos registros.

Escolha o resultado de que precisa: reduzir repetições consecutivas em uma sequência de eventos, contar valores no arquivo todo ou mostrar apenas os grupos que se repetem. Se a ordem dos eventos for importante, preserve o original e decida antes se faz sentido ordenar as linhas com sort.

Sintaxe e implementação

uniq [opções] [entrada [saída]]

Os colchetes indicam argumentos opcionais; a linha descreve a sintaxe e não deve ser executada literalmente. Sem arquivo de entrada, uniq recebe a entrada padrão, por exemplo, por um pipe (|); sem arquivo de saída, escreve na saída padrão, normalmente o terminal. Confira uniq --version, uniq --help ou man uniq na implementação instalada. Os exemplos seguem o GNU Coreutils.

Preparar arquivos e reduzir repetições vizinhas

Abra uma sessão de terminal Bash dedicada ao exercício, em um diretório onde possa criar uma pasta. O bloco cria uma pasta exclusiva e quatro arquivos de texto. O encadeamento com && interrompe o restante do bloco se uma preparação falhar. Use essa mesma sessão nos exemplos seguintes.

uniq_demo=$(mktemp -d ./uniq-demo.XXXXXX) &&
cd "$uniq_demo" &&
export LC_ALL=C &&
printf 'apple\napple\nbanana\napple\n' > events.txt &&
printf 'apple\nbanana\napple\napple\npear\n' > names.txt &&
printf 'Apple\napple\nBANANA\nbanana\n' > case.txt &&
printf '01 ready\n02 ready\n03 busy\n04 ready\n' > fields.txt &&
uniq events.txt

A última linha retorna apple, banana e apple, uma linha por valor. As duas primeiras linhas iguais viram uma, mas o último apple continua porque estava separado delas por banana. Confira cat events.txt: o arquivo ainda contém as quatro linhas originais.

LC_ALL=C estabelece a localidade C nesta sessão e nos comandos iniciados por ela, para repetir as comparações do exercício. Ao fechar o terminal dedicado, o ajuste deixa de afetar comandos futuros. A pasta de prática fica disponível; não há remoção automática de seus arquivos.

Contar valores no arquivo inteiro

names.txt contém cinco linhas: apple, banana, apple, apple e pear. Para juntar as três ocorrências de apple, ordene antes de contar:

sort names.txt | uniq -c

A saída informa 3 apple, 1 banana e 1 pear, com espaços antes dos números. A soma das contagens é 5, o total de linhas do arquivo. O pipe leva a saída ordenada de sort à entrada de uniq; o arquivo original permanece na mesma ordem.

A comparação depende da localidade, ou locale, que define regras de idioma e comparação. No exercício, a configuração C vale para os dois comandos. Se usar apenas uma atribuição antes de sort em um pipe, ela não passa automaticamente a valer para uniq. Para limitar o ambiente à operação completa, uma alternativa é (export LC_ALL=C; sort names.txt | uniq -c). Essa configuração não produz uma ordem alfabética específica do português.

Mostrar grupos repetidos ou que ocorreram uma vez

Depois de ordenar names.txt, apple forma um grupo de três linhas, enquanto banana e pear formam grupos de uma linha. Para exibir somente um representante do grupo repetido:

sort names.txt | uniq -d

O resultado é uma linha: apple. A opção -d não imprime as três ocorrências; para mostrar todas as linhas de grupos repetidos, o GNU oferece -D. Neste exercício, sort names.txt | uniq -D produz três linhas apple.

Por outro lado, sort names.txt | uniq -u retorna banana e pear. uniq -u seleciona grupos com uma ocorrência; ele não equivale a listar todos os valores distintos. Para esse último objetivo, sort names.txt | uniq retorna apple, banana e pear.

Sem ordenar, a mesma opção trata os grupos que já existem na entrada. Em uniq -u events.txt, a saída é banana e apple: esse último apple forma um grupo de uma linha, embora o valor também exista no começo do arquivo.

Comparar a contagem antes e depois de ordenar

Este exemplo recebe quatro linhas pela entrada padrão e preserva a ordem dos grupos encontrados:

printf 'apple\napple\nbanana\napple\n' | uniq -c

Saída obtida com GNU uniq 8.32 do Git para Windows, em Bash com LC_ALL=C, incluindo o recuo das contagens:

      2 apple
      1 banana
      1 apple

Existem três grupos consecutivos: dois apple, um banana e outro apple. Isso não significa que apple apareceu só duas vezes no arquivo. Depois de ordenar os mesmos dados, sort events.txt | uniq -c retorna 3 apple e 1 banana. O espaçamento de apresentação pode variar em outra implementação; a diferença importante é o agrupamento.

Ignorar maiúsculas e campos iniciais

Em case.txt, uniq -i case.txt retorna Apple e BANANA: cada par vizinho é comparado sem distinguir maiúsculas de minúsculas, e o primeiro texto do grupo permanece como representante. O teste usa letras ASCII na localidade C; não presuma que todos os alfabetos e localidades tenham as mesmas regras de caixa. Para agrupar essas formas em um arquivo que não esteja nessa ordem, alinhe os critérios dos dois comandos, por exemplo, sort -f case.txt | uniq -i.

Em fields.txt, os números iniciais são diferentes, mas as duas primeiras mensagens são ready. O comando uniq -f 1 fields.txt ignora o primeiro campo na comparação e retorna 01 ready, 03 busy e 04 ready. O campo ignorado continua na saída. O último ready permanece porque busy o separa do primeiro grupo.

Para -f, campo significa uma sequência de espaços ou tabulações seguida de caracteres que não são esses separadores. A opção pula campos e compara o restante da linha; ela não escolhe uma coluna isolada nem define um separador CSV. Se dados diferentes forem ignorados ou considerados equivalentes por -i, confira se reduzir o grupo a uma linha preserva as informações de que precisa.

Opções principais

Opção Resultado por grupo consecutivo
-c Acrescenta a contagem antes da linha representativa.
-d Mostra uma linha dos grupos que têm repetições.
-u Mostra apenas grupos com uma ocorrência.
-i Ignora diferenças entre maiúsculas e minúsculas na comparação.
-f N Pula os N primeiros campos ao comparar e mantém esses campos na saída.
-D No GNU, mostra todas as linhas dos grupos repetidos.

Gravar a saída preservando a entrada

Para salvar o resultado de prática em um nome novo, execute (set -C; uniq events.txt > events-clean.txt). Depois de sucesso, confira cat events-clean.txt e compare com o original. O ajuste set -C fica limitado ao comando entre parênteses e impede que esse arquivo de saída regular seja sobrescrito se já existir.

Não use o mesmo caminho como entrada e saída, seja por redirecionamento do shell ou pelo argumento de saída de uniq. O arquivo pode ser esvaziado ou a operação pode falhar. Escolha um nome diferente e preserve uma cópia independente antes de substituir dados importantes.

Pergunta frequente

Por que uniq não elimina repetições que estão separadas?

Ele forma grupos comparando linhas vizinhas, sem procurar todas as ocorrências do arquivo. Ordenar antes reúne os valores iguais, mas muda a sequência dos registros. Se precisa manter a ordem original, preserve a entrada e escolha uma estratégia que corresponda ao significado de duplicata no seu caso.

Documentação oficial

Consulte a documentação do GNU uniq sobre grupos e opções de comparação e a página de manual publicada pelo Debian. Compare as opções com a ajuda disponível no seu sistema.