Eu resolvi a sed
resposta pouco tempo depois de postar esta pergunta; ninguém mais usou sed
até agora, aqui está:
sed '$!N;/^\(.*\)\n\1$/d;P;D'
Um pouco de brincadeira com o problema mais geral (e a exclusão de linhas em conjuntos de três? Ou quatro ou cinco?) Forneceu a seguinte solução extensível:
sed -e ':top' -e '$!{/\n/!{N;b top' -e '};};/^\(.*\)\n\1$/d;P;D' temp
Estendido para remover triplos de linhas:
sed -e ':top' -e '$!{/\n.*\n/!{N;b top' -e '};};/^\(.*\)\n\1\n\1$/d;P;D' temp
Ou para remover quads de linhas:
sed -e ':top' -e '$!{/\n.*\n.*\n/!{N;b top' -e '};};/^\(.*\)\n\1\n\1\n\1$/d;P;D' temp
sed
possui uma vantagem adicional sobre a maioria das outras opções, que é a capacidade de operar verdadeiramente em um fluxo, sem mais memória necessária do que o número real de linhas a serem verificadas quanto a duplicatas.
Como o cuonglm apontou nos comentários , é necessário definir o código de idioma para C para evitar falhas na remoção adequada das linhas que contêm caracteres de vários bytes. Portanto, os comandos acima se tornam:
LC_ALL=C sed '$!N;/^\(.*\)\n\1$/d;P;D' temp
LC_ALL=C sed -e ':top' -e '$!{/\n/!{N;b top' -e '};};/^\(.*\)\n\1$/d;P;D' temp
LC_ALL=C sed -e ':top' -e '$!{/\n.*\n/!{N;b top' -e '};};/^\(.*\)\n\1\n\1$/d;P;D' temp
# Etc.
C
, caso contrário, no código de vários bytes, o caractere inválido nesse código de idioma causa a falha do comando.Não é muito elegante, mas é o mais simples que consigo:
O substr () apenas apara a
uniq
saída. Isso funcionará até que você tenha mais de 9.999.999 duplicatas de uma linha (nesse caso, a saída da uniq pode ultrapassar 9 caracteres).fonte
uniq -c input | awk '{if ($1 %2 == 1) { print $2 } }'
e parecia funcionar igualmente bem. Alguma razão para asubstr
versão ser melhor?$2
não$NF
seria mais robusto?foo bar
,.uniq
(pelo menos nos coreutils do GNU) parece usar de maneira confiável exatamente 9 caracteres antes do próprio texto; Não consigo encontrar isso documentado em nenhum lugar, e não está nas especificações do POSIX .Experimente este
awk
script abaixo:Supõe-se que o
lines.txt
arquivo esteja classificado.O teste:
fonte
Com
pcregrep
para uma determinada amostra:ou de uma maneira mais geral:
fonte
Se a entrada for classificada:
fonte
pineapple\napple\ncoconut
e a saída épinecoconut
.\n
vez de$
receber o/m
modificador, mas percebi que o uso$
deixaria uma linha em branco no lugar das linhas excluídas. Parece bom agora; Eu removi a versão incorreta, pois acabou de adicionar ruído. :)Eu gosto
python
disso, por exemplo, compython
2.7+fonte
Como entendi a pergunta que optei pelo awk, usando um hash de cada registro, neste caso, estou assumindo que RS = \ n, mas pode ser alterado para considerar qualquer outro tipo de arranjo, pode ser arranjado para considerar um número par de repetições, em vez de ímpares, com um parâmetro ou uma pequena caixa de diálogo. Cada linha é usada como o hash e sua contagem é aumentada. No final do arquivo, a matriz é digitalizada e imprime todas as contagens iguais do registro. Estou incluindo a contagem para verificar, mas remover um [x] é suficiente para resolver esse problema.
HTH
código de linhas de contagem
Dados de amostra:
Exemplo de execução:
fonte
awk
código, mas infelizmenteawk
as matrizes associativas não são ordenadas, nem preservam a ordem.sort
.!=0
está implícito pela forma comoawk
converte números para verdadeiros falsos valores /, tornando este redutível aawk '{a[$0]++}END{for(x in a)if(a[x]%2)print x}'
Se a entrada for classificada, e quanto a isso
awk
:fonte
com perl:
fonte
Usando construções de shell,
fonte
$b
).Quebra-cabeça divertido!
Em Perl:
Verbosamente em Haskell:
Concertamente em Haskell:
fonte
uma versão: eu uso "delimitadores" para simplificar o loop interno (assume que a primeira linha não está
__unlikely_beginning__
e assume que o texto não está terminando com a linha:__unlikely_ending__
e adicione essa linha delimitadora especial no final das linhas inseridas. algoritmo pode assumir ambos:)Então :
fonte