Existe alguma solução melhor para imprimir linhas exclusivas que não sejam uma combinação de sort
e uniq
?
command-line
text-processing
Deixe me ser
fonte
fonte
sort
(por exemplo: GNU coreutils) usam arquivos temporários e fusesort externo se a entrada for grande demais para caber na RAM. E a maioria das outras versões tem uma-m
opção, para que isso possa ser feito explicitamente dividindo a entrada (por exemplo, comsplit
), classificando cada bloco e depois mesclando os blocosRespostas:
Para imprimir cada linha idêntica apenas uma, em qualquer ordem:
Para imprimir apenas as linhas exclusivas, em qualquer ordem:
Para imprimir cada linha idêntica apenas uma vez, na ordem da primeira ocorrência: (para cada linha, imprima a linha se ainda não tiver sido vista e, em qualquer caso, aumente o contador visto)
Para imprimir apenas as linhas exclusivas, na ordem da primeira ocorrência: (registre cada linha
seen
e tambémlines
se for a primeira ocorrência; no final da entrada, imprima as linhas na ordem de ocorrência, mas apenas as que são vistas apenas uma vez)fonte
awk '!seen[$0]++ {print}'
?awk '!seen[$0]++'
, pois o{print}
é implícito por um comando vazio.Algumas (a maioria?) Versões de
sort
possuem uma-u
bandeira que faz auniq
parte diretamente. Pode haver algumas restrições de comprimento de linha, dependendo da implementação, mas você já as possui com o plainsort|uniq
.fonte
sort -u
volta ao V7 pelo menos.-u
mas também têm, uma restrição de comprimento de linha de 512 caracteres. (Na verdade, eu acho que algo em torno de Solaris 9 Sun elevou-o para 5120. GNU ainda ganha, no entanto.)Perl funciona para você? Ele pode manter as linhas na ordem original, mesmo que as duplicatas não sejam adjacentes. Você também pode codificá-lo em Python, ou
awk
.Que pode ser reduzido para apenas
Arquivo de entrada fornecido:
Rende a saída:
fonte
use strict;
ouuse warnings;
(na verdade,strict
é o mais relevante aqui), não há reclamação sobre o uso%lines
antes de ser definido. Se executado com restrições, seria necessário haver uma linhamy %lines;
antes do loop. Observe também que o hash é%lines
; um elemento do hash é referenciado usando a$lines{$_}
notaçãosort
soluções podem ser melhores para grande quantidade de dados (o OP estava preocupado em "armazenar o arquivo inteiro na memória").sort
executará uma classificação fora do núcleo se os dados forem maiores que a memória disponível.Para a última parte da resposta mencionada em: Imprimir linhas exclusivas do @Gilles como resposta a esta pergunta, tentei eliminar a necessidade de usar dois hashes.
Esta solução é para: Imprimir apenas as linhas exclusivas, na ordem da primeira ocorrência:
awk '{counter[$0]++} END {for (line in counter) if (counter[line]==1) print line}'
Aqui, "counter" armazena uma contagem de cada linha semelhante à processada anteriormente.
No final, imprimimos apenas as linhas que têm valor de contador como 1.
fonte