Comando ou script do Linux contando linhas duplicadas em um arquivo de texto?

116

Se eu tiver um arquivo de texto com o seguinte conteúdo

red apple
green apple
green apple
orange
orange
orange

Existe um comando ou script do Linux que posso usar para obter o seguinte resultado?

1 red apple
2 green apple
3 orange
timeon
fonte

Respostas:

214

Envie-o sort(para colocar os itens adjacentes juntos) e depois uniq -cpara fazer as contagens, ou seja:

sort filename | uniq -c

e para obter essa lista em ordem (por frequência), você pode

sort filename | uniq -c | sort -nr
emprestável
fonte
48

Quase o mesmo que borribles ', mas se você adicionar o dparâmetro a uniqele mostra apenas duplicatas.

sort filename | uniq -cd | sort -nr
Jaberino
fonte
1
Perfeito para a pequena -dnota.
setembro de
6

uniq -c file

e caso o arquivo ainda não esteja classificado:

sort file | uniq -c

Mhyfritz
fonte
3

Tente isto

cat myfile.txt| sort| uniq
Rahul
fonte
sem os sinalizadores -c ou -d, o uniq não distingue linhas duplicadas de não duplicadas, ou estou faltando alguma coisa?
drevicko
2
cat <filename> | sort | uniq -c
Pajton
fonte
2

Você pode viver com uma lista ordenada em ordem alfabética:

echo "red apple
> green apple
> green apple
> orange
> orange
> orange
> " | sort -u 

?

green apple
orange
red apple

ou

sort -u FILE

-u significa único, e a exclusividade só é alcançada por meio da classificação.

Uma solução que preserva a ordem:

echo "red apple
green apple
green apple
orange
orange
orange
" | { old=""; while read line ; do   if [[ $line != $old ]]; then  echo $line;   old=$line; fi ; done }
red apple
green apple
orange

e, com um arquivo

cat file | { 
old=""
while read line
do
  if [[ $line != $old ]]
  then
    echo $line
    old=$line
  fi
done }

Os dois últimos removem apenas duplicatas, que seguem imediatamente - o que se encaixa no seu exemplo.

echo "red apple
green apple
lila banana
green apple
" ...

Vai imprimir duas maçãs, divididas por uma banana.

Usuário desconhecido
fonte
0

Para obter apenas uma contagem:

$> egrep -o '\w+' fruits.txt | sort | uniq -c

      3 apple
      2 green
      1 oragen
      2 orange
      1 red

Para obter uma contagem classificada:

$> egrep -o '\w+' fruits.txt | sort | uniq -c | sort -nk1
      1 oragen
      1 red
      2 green
      2 orange
      3 apple

EDITAR

Aha, isso NÃO foi ao longo dos limites das palavras, meu mal. Este é o comando a ser usado para linhas completas:

$> cat fruits.txt | sort | uniq -c | sort -nk1
      1 oragen
      1 red apple
      2 green apple
      2 orange
Chris Eberle
fonte
0

Aqui está um script python simples usando o tipo Counter . A vantagem é que isso não exige a classificação do arquivo, basicamente usando memória zero:

import collections
import fileinput
import json

print(json.dumps(collections.Counter(map(str.strip, fileinput.input())), indent=2))

Resultado:

$ cat filename | python3 script.py
{
  "red apple": 1,
  "green apple": 2,
  "orange": 3
}

ou você pode usar uma linha simples:

$ cat filename | python3 -c 'print(__import__("json").dumps(__import__("collections").Counter(map(str.strip, __import__("fileinput").input())), indent=2))'
Orestisf
fonte