Команда или сценарий Linux, подсчитывающий повторяющиеся строки в текстовом файле?

116

Если у меня есть текстовый файл со следующим содержанием

red apple
green apple
green apple
orange
orange
orange

Есть ли команда или сценарий Linux, которые я могу использовать для получения следующего результата?

1 red apple
2 green apple
3 orange
timeon
источник

Ответы:

215

Отправьте его sort(чтобы соединить соседние элементы), а затем uniq -cподсчитать, то есть:

sort filename | uniq -c

и чтобы получить этот список в отсортированном порядке (по частоте), вы можете

sort filename | uniq -c | sort -nr
borrible
источник
48

Практически то же самое, что и borribles, но если вы добавите dк uniqнему параметр, будут отображаться только дубликаты.

sort filename | uniq -cd | sort -nr
Jaberino
источник
1
Большой палец вверх за небольшую -dзаметку.
сентябрь
6

uniq -c file

и если файл еще не отсортирован:

sort file | uniq -c

Мифриц
источник
3

Попробуй это

cat myfile.txt| sort| uniq
Рахул
источник
без флагов -c или -d uniq не отличает повторяющиеся строки от недубликатов, или мне что-то не хватает?
drevicko
2

Можете ли вы жить с алфавитным упорядоченным списком:

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

?

green apple
orange
red apple

или

sort -u FILE

-u означает уникальный, а уникальность достигается только путем сортировки.

Решение, сохраняющее порядок:

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

и с напильником

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

Последние два удаляют только дубликаты, которые следуют сразу же, что соответствует вашему примеру.

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

Напечатает два яблока, разделенных бананом.

Пользователь неизвестен
источник
0

Чтобы просто подсчитать:

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

      3 apple
      2 green
      1 oragen
      2 orange
      1 red

Чтобы получить отсортированное количество:

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

РЕДАКТИРОВАТЬ

Ага, это было НЕ по границам слов, моя беда. Вот команда, которую нужно использовать для полных строк:

$> cat fruits.txt | sort | uniq -c | sort -nk1
      1 oragen
      1 red apple
      2 green apple
      2 orange
Крис Эберли
источник
0

Вот простой скрипт на Python, использующий тип Counter . Преимущество в том, что это не требует сортировки файла, по сути, с использованием нулевой памяти:

import collections
import fileinput
import json

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

Вывод:

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

или вы можете использовать простой однострочный:

$ cat filename | python3 -c 'print(__import__("json").dumps(__import__("collections").Counter(map(str.strip, __import__("fileinput").input())), indent=2))'
orestisf
источник