Polecenie Linuksa czy skrypt liczący zduplikowane linie w pliku tekstowym?

Jeśli mam plik tekstowy z następującym konentem

red apple
green apple
green apple
orange
orange
orange

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

1 red apple
2 green apple
3 orange
Author: user unknown, 2011-06-22

8 answers

Prześlij go przez sort (aby złożyć sąsiadujące elementy razem) następnie uniq -c aby podać liczniki, tzn.:

sort filename | uniq -c

I aby uzyskać tę listę w porządku posortowanym (według częstotliwości) Można

sort filename | uniq -c | sort -nr
 224
Author: borrible,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-22 22:55:23

Prawie taki sam jak borribles, ale jeśli dodasz d param do uniq to wyświetla tylko duplikaty.

sort filename | uniq -cd | sort -nr
 50
Author: Jaberino,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-15 07:42:20

uniq -c file

I w przypadku, gdy plik nie jest już posortowany:

sort file | uniq -c

 6
Author: mhyfritz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-22 22:53:26
cat <filename> | sort | uniq -c
 3
Author: pajton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-22 22:54:42

Spróbuj tego

cat myfile.txt| sort| uniq
 2
Author: Rahul,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-22 22:55:04

Czy można ż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 unique, a wyjątkowość jest osiągana tylko poprzez sortowanie.

Rozwiązanie zachowujące 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, z plikiem

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

Dwa ostatnie usuwają tylko 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.

 2
Author: user unknown,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-22 23:04:23

Aby po prostu policzyć:

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

      3 apple
      2 green
      1 oragen
      2 orange
      1 red

Aby uzyskać uporządkowaną liczbę:

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

EDIT

Aha, to nie było na granicy słowa, mój błąd. Oto polecenie do użycia dla pełnych linii:
$> cat fruits.txt | sort | uniq -c | sort -nk1
      1 oragen
      1 red apple
      2 green apple
      2 orange
 0
Author: Chris Eberle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-22 22:55:51

Oto prosty skrypt Pythona wykorzystujący typ licznika . Zaletą jest to, że nie wymaga to sortowania pliku, zasadniczo przy użyciu pamięci zerowej:

import collections
import fileinput
import json

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

Wyjście:

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

Lub możesz użyć prostej jednowierszowej:

$ cat filename | python3 -c 'print(__import__("json").dumps(__import__("collections").Counter(map(str.strip, __import__("fileinput").input())), indent=2))'
 0
Author: orestisf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-07-21 08:59:31