Em todo lugar que vejo alguém precisando obter uma lista exclusiva e classificada, eles sempre acessam sort | uniq
. Eu nunca vi nenhum exemplo em que alguém use sort -u
. Por que não? Qual é a diferença e por que é melhor usar o uniq do que o sinalizador exclusivo para classificar?
120
Respostas:
sort | uniq
existia antessort -u
e é compatível com uma ampla gama de sistemas, embora quase todos os sistemas modernos sejam compatíveis-u
- é o POSIX. É principalmente um retrocesso para os dias emsort -u
que não existia (e as pessoas não tendem a mudar seus métodos se a maneira que eles sabem continuar a funcionar, basta olharifconfig
contra aip
adoção).Os dois provavelmente foram mesclados porque a remoção de duplicatas em um arquivo requer classificação (pelo menos no caso padrão) e é um caso de uso extremamente comum da classificação. Também é mais rápido internamente como resultado de poder realizar as duas operações ao mesmo tempo (e devido ao fato de não exigir IPC entre
uniq
esort
). Especialmente se o arquivo for grande,sort -u
provavelmente usará menos arquivos intermediários para classificar os dados.No meu sistema, eu sempre obtenho resultados como este:
Ele também não mascarar o código de retorno
sort
, que pode ser importante (em conchas modernas existem maneiras de conseguir isso, por exemplo,bash
da$PIPESTATUS
matriz, mas isso nem sempre era verdade).fonte
sort | uniq
porque, em 9 vezes em 10, estou realmente procurandouniq -c
.sort -u
fazia parte da 7ª Edição UNIX, por volta de 1979. As versõessort
sem suporte para-u
são verdadeiramente arcaicas - ou foram escritas sem atenção ao padrão de fato antes do padrão de jure do POSIX. Veja também Stack Overflow Sort & uniq no shell Linux a partir de 2010.ip
. É 2016 e este post em 2013, mas agora só sei sobreip
comando.uniq -c
"(e talvez canalizando mais uma vezsort -nr | head
)". Fiquei me perguntando o que é equivalentesort | uniq
no Vim quando descobri que o Vim tem:sort u
comando. E o TIL tambémsort -u
existe.sort -n | uniq
vs.sort -n -u
. Por exemplo, espaços em branco à direita e à esquerda serão vistos como duplicados pelosort -n -u
mas não pelo anterior!echo -e 'test \n test' | sort -n -u
retornatest
, masecho -e 'test \n test' | sort -n | uniq
retorna as duas linhas.Uma diferença é que
uniq
existem várias opções adicionais úteis, como ignorar campos para comparação e contar o número de repetições de um valor.sort
O-u
sinalizador de apenas implementa a funcionalidade douniq
comando sem adornos .fonte
sort -u
Não é possível transmitir a saída deuniq
para usar algumas das opções úteis desta última, como pular campos para comparação e contar o número de repetições".Com
sort
s e s compatíveis com POSIXuniq
(uniq
atualmente, o GNU não é compatível com isso), há uma diferença nosort
uso do algoritmo de intercalação do código do idioma para comparar seqüências de caracteres (normalmente será usadostrcoll()
para comparar sequências) enquantouniq
verifica a identidade de valor de byte (normalmente será usadostrcmp()
) .Isso importa por pelo menos duas razões.
Em algumas localidades, especialmente nos sistemas GNU, existem caracteres diferentes que são iguais. Por exemplo, no código de idioma en_US.UTF-8 em um sistema GNU, todos os caracteres ①②③④⑤⑥⑦⑧⑨⑩ ... e muitos outros classificam da mesma forma porque sua ordem de classificação não está definida. Os dígitos arábicos 0123456789 têm a mesma classificação de seus equivalentes árabes orientais (٠١٢٣٤٥٦٧٨٩).
Para
sort -u
, orts é igual a ② e 0123 o mesmo que ٠١٢٣, portantosort -u
, retém apenas um de cada um, enquanto que parauniq
(não o GNUuniq
que usastrcoll()
(exceto com-i
)), ① é diferente de ② e 0123 diferente de ٠١٢٣, portantouniq
consideraria tudo 4 únicos.strcoll
só pode comparar cadeias de caracteres válidos (o comportamento é indefinido conforme POSIX quando a entrada possui sequências de bytes que não formam caracteres válidos) enquantostrcmp()
não se importa com caracteres, uma vez que faz apenas comparação de bytes a bytes. Portanto, esse é outro motivo pelo qual vocêsort -u
pode não fornecer todas as linhas exclusivas se algumas delas não formarem texto válido.sort|uniq
, embora ainda não especificado na entrada que não seja de texto, na prática é mais provável que você forneça linhas exclusivas por esse motivo.Além dessas sutilezas, uma coisa que não foi notada até agora é que
uniq
compara a linha inteira lexicamente, enquantosort
a-u
compara com base na especificação de classificação fornecida na linha de comando.fonte
Prefiro usar
sort | uniq
porque, quando tento usar a opção-u
(eliminar duplicatas) para remover duplicatas que envolvem seqüências de maiúsculas e minúsculas, não é tão fácil entender o resultado.Nota: para poder executar os exemplos abaixo, você precisa simular a sequência de intercalação C padrão, fazendo o seguinte:
Por exemplo, se eu quiser classificar um arquivo e remover duplicatas, mantendo ao mesmo tempo os diferentes casos de strings.
Essa confusão é resolvida não usando a
-u
opção para remover duplicatas. O usouniq
é mais previsível. O primeiro abaixo classifica e ignora o caso e depois o passauniq
para remover as duplicatas.fonte
-u
opção de gerarsort
a primeira de uma corrida igual (consulte a página de manual). Assim,sort -fu
capta a primeira ocorrência de cada linha exclusiva que não diferencia maiúsculas de minúsculas. A lógicasort
usada para remover duplicatas é previsível.Outra diferença que descobri hoje é ao classificar com base em um delimitador onde
sort -u
aplica o sinalizador exclusivo apenas na coluna que você classifica.fonte