Isto é o que eu faço, no entanto, algoritmicamente, isso não parece ser a abordagem mais eficiente (O (n log n) * avg_line_len onde n é o número de linhas). Estou trabalhando em arquivos com vários gigabytes de tamanho, portanto o desempenho é uma questão fundamental. Gostaria de saber se existe uma ferramenta que faça apenas a contagem em uma única passagem usando uma árvore de prefixos (no meu caso, as strings costumam ter prefixos comuns) ou similares, que devem funcionar em O (n) * avg_line_len. Alguém conhece essa ferramenta de linha de comando?
Droggl
21
Uma etapa adicional é canalizar a saída disso para um comando final 'sort -n'. Isso ordenará os resultados pelos quais as linhas ocorrem com mais frequência.
samoz
79
Se você quiser imprimir apenas linhas duplicadas, use 'uniq -d'
DmitrySandalov
6
Se você quiser classificar novamente o resultado, poderá usar sortnovamente como:sort <file> | uniq -c | sort -n
Abhishek Kashyap
413
Isso imprimirá apenas linhas duplicadas , com contagens:
Bom argumento com a opção --repeated ou -d. Muito mais preciso do que usar "| grep 2" ou similar!
22713 Lauri
Como posso modificar este comando para recuperar todas as linhas cuja contagem de repetições é superior a 100?
Black_Rider
@Black_Rider Adicionar | sort -nou | sort -nrao pipe classificará a saída pela contagem de repetições (ascendente ou descendente, respectivamente). Não é isso que você está perguntando, mas achei que poderia ajudar.
Andrea
1
@Black_Rider awk parece capaz de fazer todos os tipos de cálculos: em seu caso, você poderia fazer| awk '$1>100'
awk '{dups[$1]++} END{for (num in dups) {print num,dups[num]}}' data
No awk 'dups[$1]++'comando, a variável $1contém todo o conteúdo da coluna1 e colchetes são acesso à matriz. Portanto, para cada primeira coluna da linha no dataarquivo, o nó da matriz nomeada dupsé incrementado.
E, no final, estamos repetindo o dupsarray com a numvariável e imprimimos os números salvos primeiro e depois o número de valores duplicados dups[num].
Observe que seu arquivo de entrada possui espaços no final de algumas linhas; se você os esclarecer, poderá usar $0no lugar do $1comando acima :)
sort | uniqe a solução awk possui vantagens e desvantagens em termos de desempenho e recursos: se os arquivos são grandes e o número de linhas diferentes é pequeno, a solução awk é muito mais eficiente. É linear no número de linhas e o uso do espaço é linear no número de linhas diferentes. OTOH, a solução awk precisa manter todas as diferentes linhas na memória, enquanto a classificação (GNU) pode recorrer a arquivos temporários.
Lars Noschinski
14
Nas janelas usando o "Windows PowerShell" , usei o comando mencionado abaixo para conseguir isso
Basicamente: converta todos os caracteres de espaço em quebras de linha, classifique a saída traduzida e alimente-a para uniq e conte linhas duplicadas.
Respostas:
Supondo que haja um número por linha:
Você pode usar o
--count
sinalizador mais detalhado também com a versão GNU, por exemplo, no Linux:fonte
sort
novamente como:sort <file> | uniq -c | sort -n
Isso imprimirá apenas linhas duplicadas , com contagens:
ou, com as opções longas do GNU (no Linux):
no BSD e OSX, você deve usar o grep para filtrar linhas exclusivas:
Para o exemplo dado, o resultado seria:
Se você deseja imprimir contagens para todas as linhas, incluindo aquelas que aparecem apenas uma vez:
ou, com as opções longas do GNU (no Linux):
Para a entrada fornecida, a saída é:
Para classificar a saída com as linhas mais frequentes no topo, você pode fazer o seguinte (para obter todos os resultados):
ou, para obter apenas linhas duplicadas, as mais frequentes primeiro:
no OSX e no BSD, o final se torna:
fonte
| sort -n
ou| sort -nr
ao pipe classificará a saída pela contagem de repetições (ascendente ou descendente, respectivamente). Não é isso que você está perguntando, mas achei que poderia ajudar.| awk '$1>100'
sort FILE | uniq -c | grep -v '^ *1 '
Para localizar e contar linhas duplicadas em vários arquivos, você pode tentar o seguinte comando:
ou:
fonte
Através da awk:
No
awk 'dups[$1]++'
comando, a variável$1
contém todo o conteúdo da coluna1 e colchetes são acesso à matriz. Portanto, para cada primeira coluna da linha nodata
arquivo, o nó da matriz nomeadadups
é incrementado.E, no final, estamos repetindo o
dups
array com anum
variável e imprimimos os números salvos primeiro e depois o número de valores duplicadosdups[num]
.Observe que seu arquivo de entrada possui espaços no final de algumas linhas; se você os esclarecer, poderá usar
$0
no lugar do$1
comando acima :)fonte
uniq
?sort | uniq
e a solução awk possui vantagens e desvantagens em termos de desempenho e recursos: se os arquivos são grandes e o número de linhas diferentes é pequeno, a solução awk é muito mais eficiente. É linear no número de linhas e o uso do espaço é linear no número de linhas diferentes. OTOH, a solução awk precisa manter todas as diferentes linhas na memória, enquanto a classificação (GNU) pode recorrer a arquivos temporários.Nas janelas usando o "Windows PowerShell" , usei o comando mencionado abaixo para conseguir isso
Também podemos usar o Cmdlet where-object para filtrar o resultado
fonte
Supondo que você tenha acesso a um ambiente padrão do shell Unix e / ou cygwin:
Basicamente: converta todos os caracteres de espaço em quebras de linha, classifique a saída traduzida e alimente-a para uniq e conte linhas duplicadas.
fonte