Polecenie lub skrypt systemu Linux liczący zduplikowane wiersze w pliku tekstowym?

116

Jeśli mam plik tekstowy o następującej treści

red apple
green apple
green apple
orange
orange
orange

Czy istnieje polecenie lub skrypt systemu Linux, których mogę użyć, aby uzyskać następujący wynik?

1 red apple
2 green apple
3 orange
czas na
źródło

Odpowiedzi:

215

Prześlij go sort(aby połączyć ze sobą sąsiednie elementy), a następnie uniq -czlicza, tj .:

sort filename | uniq -c

i aby uzyskać tę listę w posortowanej kolejności (według częstotliwości), możesz

sort filename | uniq -c | sort -nr
żałosne
źródło
48

Prawie to samo, co borribles ”, ale jeśli dodasz do niego dparametr, zobaczysz uniqtylko duplikaty.

sort filename | uniq -cd | sort -nr
Jaberino
źródło
1
Kciuki w górę za małą -dnotatkę.
wrzesień
6

uniq -c file

aw przypadku, gdy plik nie jest już posortowany:

sort file | uniq -c

mhyfritz
źródło
3

Spróbuj tego

cat myfile.txt| sort| uniq
Rahul
źródło
bez flag -c lub -d, uniq nie rozróżnia wierszy zduplikowanych od tych, które nie są duplikatami, czy czegoś mi brakuje?
drevicko
2
cat <filename> | sort | uniq -c
pajton
źródło
2

Czy możesz żyć z alfabetyczną, uporządkowaną listą:

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

?

green apple
orange
red apple

lub

sort -u FILE

-u oznacza niepowtarzalność, a niepowtarzalność można osiągnąć tylko poprzez sortowanie.

Rozwiązanie, które zachowuje porządek:

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

i za pomocą pliku

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

Dwie ostatnie tylko usuwają duplikaty, które następują natychmiast - co pasuje do twojego przykładu.

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

Wydrukuje dwa jabłka podzielone przez banana.

nieznany użytkownik
źródło
0

Aby po prostu policzyć:

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

      3 apple
      2 green
      1 oragen
      2 orange
      1 red

Aby uzyskać posortowaną liczbę:

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

EDYTOWAĆ

Aha, to nie było poza granicami słów, moja wina. Oto polecenie używane dla pełnych linii:

$> cat fruits.txt | sort | uniq -c | sort -nk1
      1 oragen
      1 red apple
      2 green apple
      2 orange
Chris Eberle
źródło
0

Oto prosty skrypt w Pythonie używający typu Counter . Zaletą jest to, że nie wymaga to sortowania pliku, zasadniczo przy zerowej pamięci:

import collections
import fileinput
import json

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

Wynik:

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

lub możesz użyć prostego, jednowierszowego:

$ cat filename | python3 -c 'print(__import__("json").dumps(__import__("collections").Counter(map(str.strip, __import__("fileinput").input())), indent=2))'
orestisf
źródło